PDA

Bekijk de volledige versie : Сохраняем системное время после рестарта



furry-cheetah
22-10-2009, 21:55
Хочу поделиться скриптом для сохранения системной даты и часов после перезагрузок и выключения роутера.

Зачем это нужно?

Допустим, у вашего провайдера стоит лимит на попытки подключения. Перезагружаете роутер 3 раза, после чего провайдер 10 минут блокирует подключения, за эти 10 минут успевает обновиться статистика по трафику (vnstat например) и вы получаете графики за 1 января 1970, если есть некий бот - он напишет логи 1970 год, если не доступен сервер обновления времени NTP или провайдер блокирует порт, по которому идет обновление.
Есть еще несколько примеров, но каждый может оценить необходимость этого скрипта для себя. У меня, например часто не бывает инета, а нужно ребутнуть роутер - получается стремная статистика по локальному трафу да и приятнее сразу при загрузке иметь "почти" точное время. (Почти, потому, что оно будет отставать от реального на время с падения роутера до загрузки и монтирования дисков)

Принцип работы: Через определенные промежутки времени скрипт сохраняет текущаю дату и время в файл и при загрузке роутера востанавливает их обратно.


Jan 1 03:00:20 rc.unslung: start service /opt/etc/init.d/S01time
Jan 1 03:00:20 rc.unslung: start service /opt/etc/init.d/S05syslogd
Jan 1 03:00:20 time_script: Restoring system time: 22 Oct 2009 19:57:33
Jan 1 03:00:20 time_script: System time restored from /opt/etc/last.date
Oct 22 19:57:34 syslogd: started.
Oct 22 19:57:34 rc.unslung: start service /opt/etc/init.d/S10cron
~~~тут был кусок лога~~~
Oct 22 20:12:01 /opt/sbin/cron[396]: (admin) CMD (run-parts /opt/etc/cron.1min)
Oct 22 20:12:34 ntp client: Synchronizing time with time.nist.gov ...
Oct 22 20:18:01 /opt/sbin/cron[470]: (admin) CMD (run-parts /opt/etc/cron.1min)Как видно из примера, корректное время в системе установилось еще до запуска основных приложений, ведущих логи и статистику (веб сервер, фтп, rrd и vnstat). И только через несколько минут время синхронизировалось через инет, а за это время тот же vnstat нарисовал бы уже статистику за 1970 год (у меня обновление стоит раз в 5 минут) и то иногда не успевало время установиться :)

Что необходимо для работы:

пакет coreutils или отдельно из вложения coreutils-date
Работающий cron
Работающий rc.unslung (прилагается)
Конечно же прямые руки и немного серого вещества :D


И так, приступим.
Есть 2 пути, простой и посложнее.
Простой:
0) Если не установлен CRON ставим его по мануалу, как описано тут http://wl500g.info/showpost.php?p=128993&postcount=5
1) Скачиваем файл time.tar.gz

cd /opt/etc/ && wget http://wl500g.info/attachment.php?attachmentid=5556&d=1256245590 Можно скачать браузером и залить по фтп или самбе, считайте я написал общий случай.
2) Переходим в корень файловой системы, чтобы распаковать его:

cd / && tar -xzvf /opt/etc/time.tar.gz
Внутри архива находятся 3 файла: time.sh - ярлык на запуск скрипта (распаковывается в /opt/etc/cron.1min/) S01time - сам скрипт (распаковывается в /opt/etc/init.d/) и rc.unslung (распаковывается в /opt/etc/init.d/)
2-а) Если у вас не стоит запуск rc.unslung после монтирования диска выполните следующее:

echo "/opt/etc/init.d/rc.unslung start">>/usr/local/sbin/post-mount
flashfs save && flashfs commit && flashfs enable В противном случае пропустите этот шаг.
2-б) А теперь сделаем так, чтобы при команде reboot роутер через rc.unslung остановил все, что им запущено, в том числе сохранил время в файл и перемонтировал диски только на чтение


echo "#!/bin/sh">/usr/local/sbin/pre-shutdown
echo "/opt/etc/init.d/rc.unslung stop">/usr/local/sbin/pre-shutdown
echo "sleep 10s">/usr/local/sbin/pre-shutdown
echo "for i in `cat /proc/mounts | awk '/ext3/{print($1)}'` ; do">/usr/local/sbin/pre-shutdown
echo "mount -o remount,ro $i">/usr/local/sbin/pre-shutdown
echo "done">/usr/local/sbin/pre-shutdown
echo "swapoff -a">/usr/local/sbin/pre-shutdown
echo "sleep 1s">/usr/local/sbin/pre-shutdown
chmod +x /usr/local/sbin/
flashfs save && flashfs commit && flashfs enable Внимание! этими действиями вы полностью стираете старый файл pre-shutdown и создаете его заново. Если в нем небыло ничего ценного или его вообще не существовало - тогда это не страшно. :)
3) Установим пакет coreutils

ipkg install coreutils

На этом простой вариант установки закончен. Остается перезагрузить роутер и если все сделано правильно в папке /opt/etc/ появится файл last.date открыв который вы увидите текущее время роутера.
Частоту сохранения системного времени в файл можно менять перемещением файла time.sh из папки cron.1min например в cron.5min и т.д. В самом скрипте можете обнаружить минимальные настройки, там вы сможете изменить путь к файлу, где будет храниться системная дата и время.

Теперь вариант посложнее: для хардкорных юзверей :p
0) Если не установлен CRON ставим его по мануалу, как описано тут http://wl500g.info/showpost.php?p=128993&postcount=5
1) Создаем файл автозапуска всего из папки init.d

vi /opt/etc/init.d/rc.unslung
нажимаем "I" и вставляем:

#! /bin/sh

# Start/stop all init scripts in /opt/etc/init.d
# starting them in numerical order and
# stopping them in reverse numerical order
#
if [ $# -ne 1 ]; then
printf "Usage: $0 {start|stop}\n" >&2
exit 1
fi

daemons=`echo $(/usr/bin/dirname $0)/S??*`
[ $1 = "stop" ] && daemons=`echo $daemons | /usr/bin/tr " " "\n" | /usr/bin/sort -r`

for i in $daemons; do

# Ignore dangling symlinks (if any).
[ ! -f "$i" ] && continue

# Write to syslog
logger -t rc.unslung "$1 service $i"

case "$i" in
*.sh)
# Source shell script for speed.
(
trap - INT QUIT TSTP
set $1
. $i
)
;;
*)
# No sh extension, so fork subprocess.
$i $1
;;
esac
done
Нажимаес esc затем нажимаем вместе shift+: (шифт и двоеточие) затем wq и жмем enter.
Делаем файл исполняемым:

chmod +x /opt/etc/init.d/rc.unslung
На этом форуме видел разные варианты этого скрипта, этот самый адекватный - запускает все в папке по старшинству (чем меньше цифра после S в имени фала, тем первее он выполнится) и при рестарте роутера он останафливает по возможности все, что запустил.
2) Прописываем его в автозагрузку и автовыгрузку:
В файл
vi /usr/local/sbin/post-mount добавляем строчку
/opt/etc/init.d/rc.unslung start а в
vi /usr/local/sbin/pre-shutdown строчки
/opt/etc/init.d/rc.unslung stop
sleep 10s
for i in `cat /proc/mounts | awk '/ext3/{print($1)}'` ; do
mount -o remount,ro $i
done
swapoff -a
sleep 1s
Сохраняем (помните шифт плюс двоеточие?) повторяем процедуру как выше :) (не забываем, что в начале файлов pre-shutdown и post-boot в первой строке должно быть #!/bin/sh Если вы первый раз редактируете эти фалы, обязательно добавьте эту строку, если она уже есть, добавлять повторно не нужно)

Делаем файлы исполняемыми
chmod +x /usr/local/sbin/ и сохранием в памяти роутера
flashfs save && flashfs commit && flashfs enable
3) Создаем сам скрипт сохранения времени:

vi /opt/etc/init.d/S01time

#!/bin/sh

#Time saving script by Furry Cheetah for ASUS routers

#===Setup===
#Path, where placed "date" symlink for execute
PREFIX="/opt/bin/"
#Name of system tool to manage time
NAME=date
#File, to store system date and time
FILE=/opt/etc/last.date

#===Script===
RESTDATE=$(cat $FILE)
if [ -z "$1" ] ; then
case `echo "$0" | sed 's:^.*/\(.*\):\1:g'` in
S??*start) rc="start" ;;
S??*stop) rc="stop" ;;
S??*usage) rc="usage" ;;
S*) rc="start" ;;
esac
else
rc="$1"
fi

case "$rc" in
start)
logger -t time_script "Restoring system time: $RESTDATE" &
echo "Restoring system time: $RESTDATE" &
$PREFIX$NAME -s "$RESTDATE" &
logger -t time_script "System time restored from $FILE" &
echo "System time restored from $FILE"
;;
stop)
$PREFIX$NAME "+%d %b %Y %X">$FILE &
#Uncomment string below if you need to put message in log every time,
#when time is saving (for debug).
# logger -t time_script "Saving system time to: $FILE" &
echo "Saving system time to: $FILE"
;;
restart)
"$0" stop
;;
usage)
echo "Usage: $0 (start|stop|restart|usage)"
;;
esac

exit 0

В опциях сразу измените файл, где будут храниться параметры даты и времени, можете оставить и мое название, как вам будет угодно :) Это параметр FILE=/opt/etc/last.date Все сохраниете через esc затем shift+: затем wq

Теперь селаем файл исполняемым:
chmod +x /opt/etc/init.d/S01time

4) Установим пакет coreutils

ipkg install coreutils

furry-cheetah
22-10-2009, 21:56
5) Сохранять время вручную или только лишь при перезагрузке не очень здорово, а вдруг "свет вырубят"? Тогда время не сохранится. На этот вариант я предусмотрел сохранение почаще.
У меня стоит винт в роутере, поэтому я не заморочивался сильно и поставил сохранение каждую минуту, те у кого флешка - могут поставить 5 минут, пол часа или час. Все зависит от настроек CRON.

Создадим ярлык в одной из папок крона (crontab и папки редактируйте по мануалу в пункте №1) Для примера создадим его в папке запуска каждые 5 минут:

vi /opt/etc/cron.5mins/time.sh
Вставьте и сохраните код

#!/bin/sh
#Script for saving time in file.
#See "Setup" section for configuration in "S01time" file.
#Additional options:
#stop - for saving time
#restart - work like "stop"
#start or "blank" after S01time - restoring system time from file.
#example: "S01time.sh start" - replace your current system time from file.
#Best regards. Furry Cheetah

/opt/etc/init.d/S01time stop
Сделаем наш ярлык исполняемым:
chmod +x /opt/etc/cron.5mins/time.sh

В # скрывается коментарий по использованию, я думаю минимальными знаниями английского все владеют или накройняк путем научного "тыка" разберутся что к чему :p

После всех процедур необходимо перезагрузить роутер. В результате получаем при запуске роутера - восстановление времени и системной даты, а при ребуте, выключении через halt и каждые 5 минут, сохранение текущей даты в файл из которого и происходит восстановление.

Если есть какие вопросы или комментарии - отписывайтесь :)

net_net
23-10-2009, 10:50
я делал проще
http://wl500g.info/showthread.php?p=126141#post126141

furry-cheetah
24-10-2009, 15:31
я делал проще

Проще, но нет привязки к внезапному падению напруги в розетке. Только при "правильном" выключении и нет завязки на unslung :) А так тоже вариант. :)

mikypich
03-11-2009, 22:09
Проще, но нет привязки к внезапному падению напруги в розетке. Только при "правильном" выключении и нет завязки на unslung :) А так тоже вариант. :)

все это прекрасно. но количество циклов перезаписи современной флешки примерно 100000. нетрудно посчитать что при перезаписи раз в минуту флешка "примет ислам" через ~70 дней.
посему данная технология применима в основном к hdd.

furry-cheetah
03-11-2009, 23:27
все это прекрасно. но количество циклов перезаписи современной флешки примерно 100000. нетрудно посчитать что при перезаписи раз в минуту флешка "примет ислам" через ~70 дней.
посему данная технология применима в основном к hdd.

Согласен, что каждую минуту актуально только для HDD, для флешек я написал чуть выше выход из положения: сохранять время не каждую минуту, а каждые 5 минут, 10, пол часа или еще реже.

Все просто, перемещаем файл (отмечен жирным)

/opt/etc/cron.5mins/time.sh
в любую из папок, настроенных в CRONTAB
У меня, например, в кронтабе настроенны папки запуска:

cron.1min
cron.5mins
cron.daily
cron.hourly
cron.monthly
cron.weekly
А сам /opt/etc/crontab выглядит следующим образом:

SHELL=/bin/sh
PATH=/sbin:/bin:/usr/sbin:/usr/bin:/opt/bin:/opt/sbin:/opt/usr/bin:/opt/usr/sbin
MAILTO=""
HOME=/
# ---------- ---------- Default is Empty ---------- ---------- #
# Syntax for lines is : minute hour day month dayofweek command #
*/1 * * * * admin run-parts /opt/etc/cron.1min
*/5 * * * * admin run-parts /opt/etc/cron.5mins
0 * * * * admin run-parts /opt/etc/cron.hourly
0 0 * * * admin run-parts /opt/etc/cron.daily
0 0 * * 0 admin run-parts /opt/etc/cron.weekly
0 0 1 * * admin run-parts /opt/etc/cron.monthly

Проще говоря для флешководов - не стоит запускать time.sh чаще раза в 5 минут. Можете сделать запуск например раз в пол часа

В /opt/etc/crontab добавляем строчку
*/30 * * * * admin run-parts /opt/etc/cron.30mins и в папке /opt/etc/ создаем подпапку соответственно
cron.30mins в которую и кладем наш time.sh

P.S. Флешки устроены немного по другому, чем винты. Винт пишет куда захочет или где место есть свободное, а в флешки обычно встраивают алгоритм, который следующую запись или перезапись производит со смещением. Т.е. если на флешке есть файл и система постоянно обновляет его содержимое - контроллер памяти на флешке пишет следующее изменение этого файла не на то же место, где он находился, а рядом, со смещением. Это сделано какраз для продления ресурса флешки, чтобы поверхность памяти "изнашивалась" равномерно. Что насчет области файловой системы - хз, как там обстоят дела, никогда не задумывался, как туда идет запись на флешках. имхо.

ggR
30-09-2011, 05:42
Товарищи, подскажите, почему не сохраняются настройки даты и времени ?
Имеется RT-N16
ввожу по формату, типа date 093008002011
затем flashfs save && flashfs commit && flashfs enable && reboot
после ребута, опять 1970 год

TReX
30-09-2011, 08:28
Товарищи, подскажите, почему не сохраняются настройки даты и времени ?
Имеется RT-N16
ввожу по формату, типа date 093008002011
затем flashfs save && flashfs commit && flashfs enable && reboot
после ребута, опять 1970 год

а никто и не обещал что оно сохранится, для этого и есть синхронизация с NTP

furry-cheetah
01-10-2011, 20:05
Товарищи, подскажите, почему не сохраняются настройки даты и времени ?
Имеется RT-N16
ввожу по формату, типа date 093008002011
затем flashfs save && flashfs commit && flashfs enable && reboot
после ребута, опять 1970 год
В роутере нету батарейки и после ребута часы слетают.

У меня часы сохраняются, я скрипт писал, который каждую минуту текущее время в файл пишет и при ребуте обратно его из этого файла возвращает в систему (погрешность меньше минуты от реального), а потом уже когда появляется связь с инетом - синхронизирует его с реальным временем NTP и снова продолжает писать в файл (синхронизировать файл с реальным временем).

1970 год имеем в логе после ребута только в нескольких первых строчках, пока процесс загрузки не добирается до post_boot