PDA

Bekijk de volledige versie : Шаблон скриптов инициализации init.d



ocoka13
19-11-2006, 12:13
а что inittab отсутствует ?
Oleg а что происходит после запуска /sbin/init ?:confused:

Oleg
19-11-2006, 19:02
Нет inittab, поскольку init здесь не простой, а золотой. :) Т.е. написан специально для роутера и делает, что ему нужно.

Shajtan
23-11-2007, 23:54
Обьясните, плиз, какая епическая сила толкает (должна толкать, потому как у меня сего не происходит) стартовые скрипты из /opt/etc/init.d ?
Туплю и понять не имею разумения...

Mam(O)n
24-11-2007, 04:24
Раньше, как я помню, в старом репозитории при установки ipkg ставился скрипт /opt/etc/rc.unslung, который толкал скрипты из папки /opt/etc/init.d, начинающиеся на S плюс две цифры (для приоритета). Но соответственно его нужно было также прописывать в пост-маунт. Теперь же с новым ipkg-opt этот скрипт не ставится.

Вот содержимое того самого скрипта.

for i in /opt/etc/init.d/S??* ;do

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

case "$i" in
*.sh)
# Source shell script for speed.
(
trap - INT QUIT TSTP
set start
. $i
)
;;
*)
# No sh extension, so fork subprocess.
$i start
;;
esac

done

Mirage-net
24-11-2007, 12:40
S плюс две цифры (для приоритета)
Не приоритета, а очередности запуска ...

Mam(O)n
24-11-2007, 13:20
Да, конечно же я имел ввиду приоритет запуска.

djet
27-02-2008, 10:50
С установкой большого количества сервисов появилась проблема управления их запуском и мониторинга состояния. К сожалению, система скриптов ПО из optware не отличается последовательностью и полнотой реализации (хотя у некоторых пакетов, безусловно, встречаются полноценные решения), поэтому пришлось дорабатывать её самому. Вот что пока получилось.

rc.unslung:


#!/bin/sh

# Start/stop all init scripts in /opt/etc/init.d including symlinks
# starting them in numerical order and
# stopping them in reverse numerical order

#logger "Started $0${*:+ $*}."

ACTION=$1
CALLER=$2

if [ $# -lt 1 ]; then
printf "Usage: $0 {start|stop|restart|reconfigure|check|kill}\n" >&2
exit 1
fi

[ $ACTION = stop -o $ACTION = restart -o $ACTION = kill ] && ORDER="-r"

for i in $(/opt/bin/find /opt/etc/init.d/ -perm '-u+x' -name 'S*' | sort $ORDER ) ;
do
case "$i" in
S* | *.sh )
# Source shell script for speed.
trap "" INT QUIT TSTP EXIT
#set $1
#echo "trying $i" >> /tmp/rc.log
. $i $ACTION $CALLER
;;
*)
# No sh extension, so fork subprocess.
$i $ACTION $CALLER
;;
esac
done




rc.func:


#!/bin/sh

ACTION=$1
CALLER=$2


ansi_red="\033[1;31m";
ansi_white="\033[1;37m";
ansi_green="\033[1;32m";
ansi_yellow="\033[1;33m";
ansi_blue="\033[1;34m";
ansi_bell="\007";
ansi_blink="\033[5m";
ansi_std="\033[m";
ansi_rev="\033[7m";
ansi_ul="\033[4m";


start() {
[ "$CRITICAL" != "yes" -a "$CALLER" = "cron" ] && return 7
[ "$ENABLED" != "yes" ] && return 8
echo -e -n "Starting $DESC... "
if [ -n "`pidof $PROC`" ]; then
echo -e " $ansi_yellow already running. $ansi_white"
return 0
fi
$PRECMD > /dev/null 2>&1
$PREARGS $PROC $ARGS > /dev/null 2>&1 &
#echo $PREARGS $PROC $ARGS
COUNTER=0
LIMIT=10
while [ -z "`pidof $PROC`" -a "$COUNTER" -le "$LIMIT" ]; do
sleep 1s;
COUNTER=`expr $COUNTER + 1`
done
$POSTCMD > /dev/null 2>&1

if [ -z "`pidof $PROC`" ]; then
echo -e " $ansi_red failed. $ansi_white"
logger "Failed to start $DESC from $CALLER."
return 255
else
echo -e " $ansi_green done. $ansi_white"
logger "Started $DESC from $CALLER."
return 0
fi

}

stop() {
case "$ACTION" in
stop | restart)
echo -e -n "Shutting down $PROC... "
killall $PROC 2>/dev/null
COUNTER=0
LIMIT=10
while [ -n "`pidof $PROC`" -a "$COUNTER" -le "$LIMIT" ]; do
sleep 1s;
COUNTER=`expr $COUNTER + 1`
done
;;
kill)
echo -e -n "Killing $PROC... "
killall -9 $PROC 2>/dev/null
;;
esac


if [ -n "`pidof $PROC`" ]; then
echo -e " $ansi_red failed. $ansi_white"
return 255
else
echo -e " $ansi_green done. $ansi_white"
return 0
fi
}

check() {
echo -e -n "Checking $DESC... "
if [ -n "`pidof $PROC`" ]; then
echo -e " $ansi_green alive. $ansi_white";
return 0
else
echo -e " $ansi_red dead. $ansi_white";
return 1
fi

}

reconfigure() {
SIGNAL=SIGHUP
echo -e "Sending $SIGNAL to $PROC... "
killall -$SIGNAL $PROC 2>/dev/null
}


for PROC in $PROCS; do
case $ACTION in
start)
start
;;
stop | kill )
check && stop
;;
restart)
check > /dev/null && stop
start
;;
check)
check
;;
reconfigure)
reconfigure
;;
*)
echo -e "Usage: $0 (start|stop|restart|check|kill|reconfigure)"
exit 1
;;
esac
done

#logger "Leaving ${0##*/}."


S* (на примере asterisk):


#!/bin/sh

ENABLED=yes
PROCS=asterisk
ARGS="-pFvvv"
PREARGS="nice -n -20"
DESC=$PROCS
PATH=/opt/sbin:/opt/bin:/opt/usr/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

. /opt/etc/init.d/rc.func


Краткая справка, о том, как это работает и о способах применения.

rc.unslung - основной управляющий скрипт, запускающий остальные скрипты с указанным параметром. Проверяет атрибут исполнения, для отключения скрипта достаточно сделать ему chmod -x.

Применение:

инициализация сервисов после загрузки (предпочтителен запуск из post-mount)
корректное завершение до перезагрузки (pre-shutdown)
мониторинг запущенных сервисов по расписанию cron'a (подойдёт параметр start)
реконфигурация выбранных служб при изменении сетевых настроек (post-firewall) (пока никак не реализовано)
запуск по запросу


rc.func - скрипт-модуль, содержащий основные функции. Вызывается из S*.

Основные параметры:

start - запуск, перед этим осуществляется проверка на наличие уже запущенного процесса
stop - останов
restart - перезагрузка сервиса. то же самое, что stop + start
check - проверка на запущенность


S* - скрипты настроек сервисов.

Содержат переменные:

ENABLED - флаг-выключатель
PROC - имя исполняемого файла для запуска, оно же используется для проверок состояния и для завершения
ARGS - аргументы процесса
PREARGS - префикс в командной строке запуска. Например, им может быть nice или sudo с параметрами.
PRECMD и POSTCMD - команды, выполнящиеся до и после запуска основного процесса. PRECMD вызывается модально.
DESC - описание
PATH - наиболее полный список путей
CRITICAL - флаг обработки при запуске из cron'a



Такой вот черновик получился. Может, кому пригодится или общими силами допишем нечто всеобъемлющее.

*для запуска скриптов требуются findutils. Подразумеваю, что они у всех есть, как на любом порядочном линуксе.

angel_il
27-02-2008, 11:03
у меня во всех скриптах есть еще и info

al37919
27-02-2008, 11:07
а bash зачем?

djet
27-02-2008, 11:20
а bash зачем?

Лучшая совместимость с моим кодом. :) А встроенный шелл source умеет? Я только что вынес все функции в отдельный файл, в большинстве S* только шапки остались.


+ добавил сортировку порядка запуска сервисов в зависимости от задачи. Нужны findutils.
+ добавил примитивную проверку (check)

al37919
27-02-2008, 12:57
Лучшая совместимость с моим кодом.
сомневаюсь :)

А встроенный шелл source умеет?
умеет. Кстати:

. $i $1
это тот же source.

Встроенный /bin/sh не умеет разве что массивы, но у Вас их все равно нет.

Смысл универсализации с вынесением функций наружу сомнителен, т.к. у демонов могут быть свои потребности: например самба запускает 2 сервиса, а amuled должен прибивать еще и amuleweb

Стандартизация нужна на уровне способов запуска --- а они и так стандартные.

djet
27-02-2008, 13:33
сомневаюсь :)

умеет. Кстати:

. $i $1
это тот же source.

Встроенный /bin/sh не умеет разве что массивы, но у Вас их все равно нет.

Смысл универсализации с вынесением функций наружу сомнителен, т.к. у демонов могут быть свои потребности: например самба запускает 2 сервиса, а amuled должен прибивать еще и amuleweb

Стандартизация нужна на уровне способов запуска --- а они и так стандартные.
Можно и так. Просто документации по встроенному sh я не нашёл (подозреваю, что как и весь busybox, это нечто очень нестандартное и урезанное), а по bash - в изобилии. Если мне понадобится что-либо реализовать, принимать во внимание sh я точно не буду, я им даже не пользуюсь.

Насчёт служб с несколькими процессами я уже думаю, как реализовать. Это точно не проблема.

Для себя смысл в модуле я вижу в том, что мне проще обновлять код, и копипаста меньше выходит.

Кстати, нет ли удобного способа передать имя родительского скрипта в запускаемый? Нужно для разграничения между запуском, например, из post-firewall и post-mount.

al37919
27-02-2008, 13:58
У Олега sh не урезан. Строго говоря это ash. Я обычно пользую вот это описание:
http://www.freebsd.org/cgi/man.cgi?query=sh&apropos=0&sektion=0&manpath=FreeBSD+6.3-RELEASE&format=html



Кстати, нет ли удобного способа передать имя родительского скрипта в запускаемый? Нужно для разграничения между запуском, например, из post-firewall и post-mount.

Во первых есть $0
Во вторых при использовании ps из procps
ps -AF возвращает в т.ч. PPID (т.е. parent's pid)
В третьих, что то в этом роде:

awk '/Name/{print $2}' "/proc/`awk '/PPid/{print $2}' "/proc/$$/status"`/status"
выведет название той проги из которой вызвано

P.S. Эх, красивую комманду я написал --- даже стирать обидно...
В четвертых, есть переменная окружения $PPID

awk '/Name/{print $2}' "/proc/$PPID/status"

angel_il
27-02-2008, 14:05
ну вообше да, #!/opt/bin/bash сразу не заметил, моветон это.

djet
27-02-2008, 14:17
ну вообше да, #!/opt/bin/bash сразу не заметил, моветон это.
О вкусах не спорят, у вас другой шелл? :) И скрипты у меня всё равно ни фига не кросс-платформенные. :D

angel_il
27-02-2008, 15:45
О вкусах не спорят, у вас другой шелл? :) И скрипты у меня всё равно ни фига не кросс-платформенные. :D
у меня /bin/sh для всех скриптов (и дело не во вкусе).

djet
29-02-2008, 00:16
+ $2 в качестве источника вызова
+ убрал bash, пока без него всё работает
+ добавлены проверки на успешность запуска и останова, улучшена логика работы
+ простой вариант дейсвтий reconfigure и kill
+ примитивный вариант запуска нескольких демонов из одного конфига ($PROC -> $PROCS, например, PROCS="smbd nmbd"). Как лучше реализовать передачу нескольких наборов переменных в скрипте?

Практически все скрипты привёл к стандартному виду, остались только syslog и rtorrent.

Как это выглядит сейчас:


[routah:init.d] time /opt/etc/init.d/rc.unslung stop
Stopping rtorrent: rtorrent.
Checking asterisk... alive.
Shutting down asterisk... done.
Checking upnp... alive.
Shutting down upnp... done.
Checking udpxy... alive.
Shutting down udpxy... done.
Checking httpd... alive.
Shutting down busybox_httpd... done.
Checking atd... alive.
Shutting down atd... done.
Checking xinetd... alive.
Shutting down xinetd... done.
Checking cron... alive.
Shutting down cron... done.
Checking samba... alive.
Shutting down smbd... done.
Checking samba... alive.
Shutting down nmbd... done.
Checking dnsmasq... alive.
Shutting down dnsmasq... done.
Checking syslog-ng... alive.
Shutting down syslog-ng... done.

real 0m9.727s
user 0m1.210s
sys 0m4.280s

[routah:init.d] time /opt/etc/init.d/rc.unslung start
Starting syslog-ng... done.
Starting dnsmasq... done.
Starting samba... done.
Starting samba... done.
Starting cron... done.
Starting xinetd... done.
Starting atd... done.
Starting httpd... done.
Starting udpxy... done.
Starting upnp... done.
Starting asterisk... done.

real 0m6.947s
user 0m1.310s
sys 0m4.260s

[routah:init.d] time /opt/etc/init.d/rc.unslung kill
Checking syslog-ng... alive.
Killing syslog-ng... done.
Checking dnsmasq... alive.
Killing dnsmasq... done.
Checking samba... alive.
Killing smbd... done.
Checking samba... alive.
Killing nmbd... done.
Checking cron... alive.
Killing cron... done.
Checking xinetd... alive.
Killing xinetd... done.
Checking atd... alive.
Killing atd... done.
Checking httpd... alive.
Killing busybox_httpd... done.
Checking udpxy... alive.
Killing udpxy... done.
Checking upnp... alive.
Killing upnp... done.
Checking asterisk... alive.
Killing asterisk... done.
Usage: /etc/init.d/ {start|manualstart|stop|manualrestart|restart|forc e-reload}

real 0m5.157s
user 0m1.380s
sys 0m3.600s

[routah:init.d] time /opt/etc/init.d/rc.unslung start
Starting syslog-ng... done.
Starting dnsmasq... done.
Starting samba... done.
Starting samba... done.
Starting cron... done.
Starting xinetd... done.
Starting atd... done.
Starting httpd... done.
Starting udpxy... done.
Starting upnp... done.
Starting asterisk... done.

real 0m6.572s
user 0m1.260s
sys 0m3.850s

[routah:init.d] time /opt/etc/init.d/rc.unslung start
Starting syslog-ng... already running.
Starting dnsmasq... already running.
Starting samba... already running.
Starting samba... already running.
Starting cron... already running.
Starting xinetd... already running.
Starting atd... already running.
Starting httpd... already running.
Starting udpxy... already running.
Starting upnp... already running.
Starting asterisk... already running.

real 0m2.469s
user 0m0.600s
sys 0m1.850s

al37919
29-02-2008, 06:33
рекомендую проверить следующее:

добавить в pre-shutdown:


/opt/etc/init.d/rc.unslung stop

/opt/bin/ps aux > /opt/pre-shutdown.log

Я наблюдаю странную картину, что если при ручном запуске stop процессы нормально завершаются, то из pre-shutdown многие вместо завершения переходят в состояние <defunct>. Любопытно почему.

djet
29-02-2008, 08:56
Действительно, не убиваются, дажё kill'ом..


/opt/etc/init.d/rc.unslung stop ${SCRIPTNAME}
/opt/bin/ps aux > /opt/pre-shutdown.log
/opt/etc/init.d/rc.unslung kill
/opt/bin/ps aux > /opt/pre-shutdown2.log
lsof -t /opt | xargs kill -9
/opt/bin/ps aux > /opt/pre-shutdown3.log



[routah:root] grep defu /opt/pre-shutdown3.log
djet 234 0.0 0.0 0 0 ? Zs 01:58 0:00 [pppd] <defunct>
djet 238 0.0 0.0 0 0 ? Z 01:58 0:00 [pptp] <defunct>
djet 303 0.0 0.0 0 0 ? Z 01:58 0:00 [pptp] <defunct>
djet 3584 0.0 0.0 0 0 ? Zs 03:13 0:02 [syslog-ng] <defunct>
nobody 3592 0.0 0.0 0 0 ? Z 03:13 0:00 [dnsmasq] <defunct>
djet 3603 0.0 0.0 0 0 ? Zs 03:13 0:00 [smbd] <defunct>
djet 3612 0.0 0.0 0 0 ? Zs 03:13 0:03 [nmbd] <defunct>
djet 3621 0.0 0.0 0 0 ? Zs 03:13 0:00 [cron] <defunct>
djet 3632 0.0 0.0 0 0 ? Zs 03:13 0:00 [xinetd] <defunct>
nobody 3642 0.0 0.0 0 0 ? Z 03:13 0:00 [atd] <defunct>
djet 3653 0.0 0.0 0 0 ? Z 03:13 0:00 [busybox_httpd] <defunct>
djet 3664 0.0 0.0 0 0 ? Z 03:13 0:00 [udpxy] <defunct>
djet 3675 0.0 0.0 0 0 ? Z 03:13 0:07 [upnp] <defunct>
djet 3686 0.0 0.0 0 0 ? Z< 03:13 0:00 [asterisk] <defunct>

djet
01-03-2008, 08:04
рекомендую проверить следующее:

добавить в pre-shutdown:


/opt/etc/init.d/rc.unslung stop

/opt/bin/ps aux > /opt/pre-shutdown.log

Я наблюдаю странную картину, что если при ручном запуске stop процессы нормально завершаются, то из pre-shutdown многие вместо завершения переходят в состояние <defunct>. Любопытно почему.

Кажется, нашлось объяснение (http://www.experts-exchange.com/OS/Linux/Q_21014072.html):

Defunct (or zombie) process is a process that has terminated (either because it has been killed by a signal or because it has called exit()) and whose parent process has not yet received notification of its termination by executing (some form of) the wait() system call.

A zombie process exists solely as a process table entry and consumes no other resources. This entry is retained to hold the child's exit status until the parent process wants to retrieve it. The parent can also be notified asynchronously via a signal of the child's termination.

So this process doesn't consume any resources other than one entry in the process table. As jools already pointed out, there is no reason to worry about this process unless you have many defunct processes. If you have many defunct processes process table can get filled and you won't be able to start new processes.

Похоже, всё в порядке. lsof показывает, что все ресурсы освобождены после первого же stop.

djet
03-03-2008, 22:05
+ немного косметики :)

Lore
07-03-2008, 11:25
djet, спасибо большущее!
Воспользовался шаблонами. Все замечательно работает.
Есть у меня одна просьбочка... :rolleyes:
Помогите, плиз, сделать пуско-остановочный скрипт для transmission (что-то типа S77transmission).
Для меня проблема в том, что для transmission-а запускать надо transmission_watchdog, а останавливать transmissiond.
Т.е. не хватает одной PROCS. Надо как-то ее разбить на PROCS_STRT и PROCS_STP :D

djet
14-06-2008, 20:54
Добавил также флажок $CRITICAL - используется у меня в проверках состояния критически важных процессов из cron'a.

CrazyDemon
05-10-2008, 16:27
Для запуска samba3 использую скрипт S95samba:


PROCS="smbd nmbd"
ARGS="-D"
PREARGS=""
DESC=$PROCS
PATH=/opt/sbin:/opt/bin:/opt/usr/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin


При рестарте выводит:


[init.d]$ ./rc.unslung restart
Shutting down smbd... done.
Starting smbd nmbd... done.
Shutting down nmbd... done.
Starting smbd nmbd... done.
Shutting down vsftpd... done.
Starting vsftpd... done.
Starting rsync... done.
Shutting down cron... done.
Starting cron... done.
Starting syslog-ng... done.


Меня несколько смущает, что после этого висит несколько демонов smbd.



[init.d]$ ps -A | grep bd
1330 ? 00:00:00 smbd
1346 ? 00:00:00 nmbd
1362 ? 00:00:00 smbd


Так и должно быть?

CrazyDemon
05-10-2008, 19:17
Попробовал запустить syslog-ng как описано в http://wl500g.info/showthread.php?t=15834&highlight=syslog-ng

Думает секунд 10, потом выдаёт.


Starting syslog-ng... failed.


Привожу S01syslog-ng



#!/bin/sh
#
# Startup script for syslog-ng
#

PROCS=syslog-ng
ARGS=""
PREARGS="/opt/etc/init.d/log-ng"
DESC=$PROCS
PATH=/opt/sbin:/opt/bin:/opt/usr/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/opt/etc/init.d

. /opt/etc/init.d/rc.func


Т.к. предполагается, что перед запуском должен отработать ещё один скрипт то я его выделил в отдельный файл "/opt/etc/init.d/log-ng".

log-ng:


#!/bin/sh
#
# Startup script for syslog-ng
#

# copy content of original syslogd to new syslog.
cat /tmp/syslog.log >> /opt/var/log/syslog-ng.log
# remove old syslog.log
rm /tmp/syslog.log

ln -s /opt/var/log/syslog-ng.log /tmp/syslog.log

Heavy
12-11-2008, 23:26
Почему-то не запускается rc.unslung.

# ls /opt/etc/init.d
S01syslog-ng S95samba rc.unslung
все файлы chmod +x
соответственно не грузятся Syslog-ng и samba 3

[admin@Server init.d]$ cat rc.unslung
#!/bin/sh
for i in /opt/etc/init.d/S??* ;do
[ ! -f "$i" ] && continue
case "$i" in
*.sh)
(
trap - INT QUIT TSTP
set start
. $i
)
;;
*)
$i start
;;
esac


[admin@Server init.d]$ cat S01syslog-ng
#!/bin/sh
#
# Startup script for syslog-ng
#

# Stop syslogd if running
if [ -n "`pidof syslogd`" ]; then
killall syslogd 2>/dev/null
sleep 1
fi
if [ -n "`pidof klogd`" ]; then
killall klogd 2>/dev/null
sleep 1
fi
# copy content of original syslogd to new syslog.
cat /tmp/syslog.log >> /opt/var/log/syslog-ng.log
# remove old syslog.log
rm /tmp/syslog.log
ln -s /opt/var/log/syslog-ng.log /tmp/syslog.log
# Stop itself if running
if [ -n "`pidof syslog-ng`" ]; then
killall syslog-ng 2>/dev/null
sleep 2
fi

kodmis
13-11-2008, 11:41
в S01syslog-ng нет команд запуска демона.
И зачем-то в конце скрипта команда на останов syslog-ng:


.....
# Stop itself if running
if [ -n "`pidof syslog-ng`" ]; then
killall syslog-ng 2>/dev/null
sleep 2
fi

Heavy
13-11-2008, 20:55
в S01syslog-ng нет команд запуска демона.
И зачем-то в конце скрипта команда на останов syslog-ng:


.....
# Stop itself if running
if [ -n "`pidof syslog-ng`" ]; then
killall syslog-ng 2>/dev/null
sleep 2
fi


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

Мое предположение - надо куда-то вписать запуск rc.unslung. В ручную запускается все по этому скрипту, а при перезагрузке - нет. Т.е. тупо не стартует.

kodmis
14-11-2008, 07:45
Конечно надо вписать :)
в post-mount его

Heavy
14-11-2008, 18:15
Конечно надо вписать :)
в post-mount его

тогда какой смысл от syslog-ng, если он запустится только после монтирования всех устройств? Надо же видеть лог загрузки системы,а не лог того, что после загрузки.Ну, например надо видеть как монтируются устройства, как запускается самба, и т.п. Че за бред...? Какой тогда смысл менять стандартный логгер на этот? :confused:

vectorm
14-11-2008, 20:41
тогда какой смысл от syslog-ng, если он запустится только после монтирования всех устройств? Надо же видеть лог загрузки системы,а не лог того, что после загрузки.Ну, например надо видеть как монтируются устройства, как запускается самба, и т.п. Че за бред...? Какой тогда смысл менять стандартный логгер на этот? :confused:
Читаем внимательно скрипт запуска syslog-ng, чтобы понять, что до его старта работает стандартный syslog, лог которого потом обрабатывается и копируется в syslog-ng.log

begemot
18-12-2008, 14:37
поставил самбу2

она прописалась в /opt/etc/init.d/S80samba

подскажите - почему она после перезапуска не стартует, ведь вроде бы файлы из init.d должны срабатывать как автозапускаемые службы.

подскажите как поправить?

svk4286
18-12-2008, 15:31
Файл выполняемый?

chmod +x /opt/etc/init.d/S80samba

kodmis
18-02-2009, 16:56
Мой вариант скриптов начального запуска процессов. За основу взял идею djet

rc.inslug:


#!/bin/sh

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

ACTION=$1
DAEMONSDIR="`/usr/bin/dirname $0`/"
[ $ACTION = stop -o $ACTION = restart ] && ORDER="-r"
DAEMONS=`/opt/bin/find $DAEMONSDIR -perm '-u+x' -name 'S??*' | sort $ORDER`

for i in $DAEMONS; do
# Ignore dangling symlinks (if any).
[ ! -f "$i" ] && continue

case "$i" in
*.sh )
(
# Source shell script for speed.
trap - INT QUIT TSTP
set $ACTION
. $i
)
;;
*)
# No sh extension, so fork subprocess.
$i $ACTION
;;
esac
done


rc.func:


#!/bin/sh
ansi_red="\033[1;31m";
ansi_green="\033[1;32m";
ansi_yellow="\033[1;33m";
ansi_white="\033[1;37m";
ansi_blue="\033[1;34m";

ansi_bell="\007";
ansi_blink="\033[5m";
ansi_std="\033[m";
ansi_rev="\033[7m";
ansi_ul="\033[4m";

PrintMsg() {
case "$2" in
1) msgtext=${ansi_green}${1}${ansi_std};;
2) msgtext=${ansi_yellow}${1}${ansi_std};;
3) msgtext=${ansi_red}${1}${ansi_std};;
*) msgtext=${1};;
esac
echo -e -n "$msgtext"
}
# Check if $pid are running
checkpid() {
while [ -n "$1" ]; do
[ -d /proc/$1 ] && return 0
shift
done
return 1
}
#
WaitUntilRun() {
COUNTER=0; LIMIT=10
while checkpid $1 && [ "$COUNTER" -le "$LIMIT" ]; do
sleep 1s;
COUNTER=`expr $COUNTER + 1`
done
}
#
WaitUntilDown() {
proc=$1 ; [ -z "$proc" ] && proc=$PROC
COUNTER=0
LIMIT=10
while [ -z "`pidof $proc`" -a "$COUNTER" -le "$LIMIT" ]; do
sleep 1s;
COUNTER=`expr $COUNTER + 1`
done
}

# A function to find the pid of a program.
pidofproc() {
# Test syntax.
if [ "$#" = 0 ] ; then
echo "Usage: pidofproc {program}"
return 1
fi
pid=0
proc="`basename $1`"
if [ -n "$PIDFILE" ] && [ -f $PIDFILE ] ; then
pid=`cat $PIDFILE`
elif [ -f /var/run/${proc}.pid ] ; then
pid=`cat /var/run/${proc}.pid`
fi
if [ -n "$pid" ] && [ -d /proc/$pid ] ; then
echo $pid
return 0
fi
# Next try "pidof"
pid=`pidof $1` || pid=`pidof $proc`
echo $pid
return 0
}
#
start() {
res=0
# Test syntax.
if [ "$#" = 0 ] ; then
echo "Usage: start {program} [arguments] [prefix command]"
return 1
fi
proc="`basename $1`"
PrintMsg "Starting $proc... "
pid=`pidofproc $1`
[ -n "$pid" ] && { PrintMsg "already running. id:$pid\n" 2; return 255;}
if [ "$#" = 3 ]; then
$3 $1 $2 2>&1 | /usr/bin/logger -t $proc
else
$1 $2 2>&1 | /usr/bin/logger -t $proc
fi
#$1 $2 > /dev/null 2>&1
WaitUntilDown $proc
if [ -n "`pidof $proc`" ]; then
PrintMsg "done.\n" 1
logger -t $proc "started"
res=0
else
PrintMsg "failed.\n" 3 ; res=1
fi
return $res
}
#
stop() {
res=0
# Test syntax.
if [ "$#" = 0 ] ; then
echo "Usage: stop {program} [signal]"
return 1
fi
proc="`basename $1`"
# Find pid.
pid=`pidofproc $1`
# check for second arg to be kill level
killlevel="$2"
str="Shutting down $proc... "
[ -n "$killlevel" ] && str="Send signal $killlevel to $proc... "
PrintMsg "$str"
# Kill it.
if [ -z "$pid" ]; then
PrintMsg "already down.\n" 2 ; return 255
fi
if [ -z "$killlevel" ] ; then
# TERM first, then KILL if not dead
kill -TERM $pid
usleep 100000
if checkpid $pid && sleep 1 &&
checkpid $pid && sleep 3 &&
checkpid $pid ; then
kill -KILL $pid
usleep 100000
fi
# use specified level only
else
kill $killlevel $pid
fi
WaitUntilRun $pid

if checkpid $pid >/dev/null 2>&1; then
PrintMsg "failed.\n" 3 ; res=1
else
PrintMsg "done.\n" 1 ; res=0
logger -t $proc "stopped"
fi
return $res
}

В этом варианте в скриптах запуска S* просто используются функции из rc.func.
Например,
S99dc (для microdc2):


#!/bin/sh
. /opt/etc/init.d/rc.func

PROC=microdc2
DESC="$PROC"
PIDFILE=""
DAEMON="/opt/bin/$PROC"
ARGS="-c /opt/etc/microdc2/dc.conf"
PREFIX="/opt/bin/screen -dmS microdc"
CONFDIR=""

# installation check
if [ ! -x $DAEMON ]; then
echo "$DAEMON is not installed"
exit 1
fi
#microdc2 features
OLDHOME=$HOME
export HOME="/opt/var/microdc"
export LANG="ru_RU.UTF-8"

case "$1" in
start)
start "$DAEMON" "$ARGS" "$PREFIX"
res=$?
;;
stop)
stop $DAEMON
res=$?
;;
restart|force-reload)
stop $DAEMON
start "$DAEMON" "$ARGS" "$PREFIX"
res=$?
;;
*)
echo "Usage: $0 {start|stop|restart}" ; exit 1
;;
esac
export HOME=$OLDHOME
exit $res


При специфических особенностях запуска/останова сервиса в скриптах S* дописываются свои функции. Например, при остановке xinetd, нужно остановить также и сервера.
S10xinetd.sh:


#!/bin/sh

. /opt/etc/init.d/rc.func
PROC=xinetd
DESC="xinetd"
PIDFILE="/var/run/xinetd.pid"
DAEMON="/opt/sbin/$PROC"
ARGS="-f /opt/etc/xinetd.conf -pidfile $PIDFILE"
CONFDIR="/opt/etc/xinetd.d/"
#
xinetd_stop() {
stop $DAEMON -SIGTERM
res=$?
for i in ${CONFDIR}* ; do
if [ -n "`grep "^[[:space:]]*disable[[:space:]]*=[[:space:]]*no" ${i}`" ] ; then
for j in `awk -F= '/^[[:space:]]*server[[:space:]]*=[[:space:]]*.*/{ print $2 }' ${i} | sort -u`; do
d="`basename $j`"
[ -n "`pidof $d`" ] || continue
stop $j
res=$?
done
fi
done
return $res
}
#
xinetd_reconfig() {
PrintMsg "Reconfigure $PROC... "
pid=`pidofproc $DAEMON`
[ -z "$pid" ] || { PrintMsg "not running.\n" 3 ; return 255;}
kill -SIGHUP $pid
sleep 1
if [ -d /proc/$pid ]; then
PrintMsg "done.\n" 1
logger -t $PROC "reconfigured"
return 0
else
PrintMsg "failed.\n" 3 ; return 1
fi
}
# installation check
if [ ! -x $DAEMON ]; then
echo "$DAEMON is not installed"
exit 1
fi
case "$1" in
start)
start "$DAEMON" "$ARGS" ; res=$?
;;
stop)
xinetd_stop ; res=$?
;;
reload|reconfig)
xinetd_reconfig ; res=$?
;;
restart|force-reload)
xinetd_stop ; res=$?
start "$DAEMON" "$ARGS"
;;
*)
echo "Usage: $0 {start|stop|reconfig|restart}" ; res=1
;;
esac
exit $res


Ну и до кучи
S10cron (для встроенного crond):


#!/bin/sh
. /etc/init.d/rc.func
PROC=crond
DESC="$PROC"
PIDFILE=""
DAEMON="/usr/sbin/$PROC"
CONFDIR="/etc/crontabs/"
ARGS="-L /var/log/cron -c $CONFDIR"

crond_reconfig() {
PrintMsg "Reconfigure $PROC... "
pid=`pidofproc $DAEMON`
[ -z "$pid" ] || { PrintMsg "not running.\n" 3 ; return 255;}
echo "admin" >> ${CONFDIR}cron.update
sleep 1
if [ -d /proc/$pid ]; then
PrintMsg "done.\n" 1
logger -t $PROC "reconfigured"
return 0
else
PrintMsg "failed.\n" 3 ; return 1
fi
}

case "$1" in
start)
start "$DAEMON" "$ARGS"
res=$?
;;
stop)
stop "$DAEMON"
res=$?
;;
reload|reconfig)
crond_reconfig ; res=$?
;;
restart|force-reload)
stop "$DAEMON"
start "$DAEMON" "$ARGS"
res=$?
;;
*)
echo "Usage: $0 {start|stop|reconfig|restart}" ; exit 1
;;
esac
exit $res

Wolfgun
22-06-2009, 11:23
Применение:

реконфигурация выбранных служб при изменении сетевых настроек (post-firewall) (пока никак не реализовано)




А что с данным вопросом????
Хочется запускать службу и правила iptables

Rucha
03-04-2010, 14:34
По какой причине может возникать ошибка при попытке ручного запуска/стопа S-скриптов?


[root@WL init.d]$ S97Samba stop
-sh: S97Samba: not found
[root@WL init.d]$
(Файл S97Samba ессно-но есть и он запускаемый)
При этом автозагрузка всех скриптов работает.

theMIROn
03-04-2010, 14:44
По какой причине может возникать ошибка при попытке ручного запуска/стопа S-скриптов?


[root@WL init.d]$ S97Samba stop
-sh: S97Samba: not found
[root@WL init.d]$
(Файл S97Samba ессно-но есть и он запускаемый)
При этом автозагрузка всех скриптов работает.

это вам не windows
[root@WL init.d]$ ./S97Samba stop

mc-sim
08-03-2011, 20:49
Нет inittab, поскольку init здесь не простой, а золотой. :) Т.е. написан специально для роутера и делает, что ему нужно.
понимаю, что тема стара, но где можно почитать о процессе запуска роутера? Что конкретно init делает при загрузке?
спасибо.

FilimoniC
08-03-2011, 21:07
понимаю, что тема стара, но где можно почитать о процессе запуска роутера? Что конкретно init делает при загрузке?
спасибо.

Исходники )

tempik
08-03-2011, 21:17
понимаю, что тема стара, но где можно почитать о процессе запуска роутера? Что конкретно init делает при загрузке?
спасибо.
Самый простой способ понять что происходит при загрузке это скачать исходники прошивки и изучить их ... Блин FilimoniC уже сказал...
А вообще если чисто академический интерес, то исходники. Если нужно решение конкретной задачи, то опиши может есть решение не залезая в подноготную :)

Basile
08-03-2011, 21:18
Что конкретно init делает при загрузке?

А вы с какой целью интересуетесь? Может вам стоит почитать про post-boot, post-firewall и т.п.?

mc-sim
08-03-2011, 21:29
Исходники )
К сожалению, в "С" не силен :(

А вообще если чисто академический интерес, то исходники. Если нужно решение конкретной задачи, то опиши может есть решение не залезая в подноготную Собственно, вопрос более академический, нежели связан с какой-то проблемой... Хочется понять процесс загрузки пошагово... В обычном линухе, там все можно разобрать по косточкам, начиная с /etc/inittab, а тут бы хотелось понять что да как...

А вы с какой целью интересуетесь? Может вам стоит почитать про post-boot, post-firewall и т.п.?
про них уже читал :)
вот тут хотошо написано http://wiki.vectormm.net/index.php/Категория:Пользовательские_скрипты

mc-sim
08-03-2011, 21:38
например согласно инструкции: http://wl500g.info/showthread.php?t=3171
чтобы работал SSH сервер dropbear, его необходимо прописать его в /usr/local/sbin/post-boot, но по умолчанию, в прошивке 1.9.2.7-rtn-r2274 на RT-N16 нет данного файла, но SSH тем не менее настраивается через веб морду и работает. Вот и интересно, кто и как и по каким конфигам его запускает...

tempik
08-03-2011, 21:40
К сожалению, в "С" не силен :(
Собственно, вопрос более академический, нежели связан с какой-то проблемой... Хочется понять процесс загрузки пошагово... В обычном линухе, там все можно разобрать по косточкам, начиная с /etc/inittab, а тут бы хотелось понять что да как...

Исходники прошивки не всегда в "С"... Прошивка это совокупность всего, что в нее включено (скомпилированный исходник кода, включенные файлы конфигураций, etc ...) Попробуй скачать скачать и посмотреть ... скрипты они и в Африке скрипты ... Может поможет ...
З.Ы. Хотя, не зная основ, зачем академический интерес ???

tempik
08-03-2011, 21:46
например согласно инструкции: http://wl500g.info/showthread.php?t=3171
чтобы работал SSH сервер dropbear, его необходимо прописать его в /usr/local/sbin/post-boot, но по умолчанию, в прошивке 1.9.2.7-rtn-r2274 на RT-N16 нет данного файла, но SSH тем не менее настраивается через веб морду и работает. Вот и интересно, кто и как и по каким конфигам его запускает...
Раньше его делали в ручную, теперь это встроенная функция. И все берет из nvram. Короче понятно (форум читать не желаю, расскажите все заново). Читать FAQ и форум ...

stupid Fry
11-09-2011, 03:30
Спасибо djet (http://wl500g.info/member.php?u=10719) за полезный скрипт (http://wl500g.info/showpost.php?p=85182&postcount=1).

Только вот если кто-то, как и я, использует не стандартную цветовую схему (белые символы на чёрном фоне), то после запуска скрипта вручную, символы изменят цвет на белый.

Что-бы этого избежать, можно сделать так:
изменить

ansi_white="\033[1;37m"
на

ansi_white="\033[0m"
Это вернёт цвета по умолчанию.

Думаю знающие люди и без меня так сделали, но таким, не очень знающим :( как я, это может пригодиться.

dlink
22-05-2012, 13:22
все ли файлы в init.d должны быть исполняемыми (начинаться на #!/bin/sh и иметь chmod +x)? у меня присутствует файл rc.func который начинается на #!/bin/sh но не имеет атрибута исполняемого в свойствах файла.

ryzhov_al
22-05-2012, 13:34
все ли файлы в init.d должны быть исполняемыми (начинаться на #!/bin/sh и иметь chmod +x)? у меня присутствует файл rc.func который начинается на #!/bin/sh но не имеет атрибута исполняемого в свойствах файла.Посмотрите в любой стартовый скрипт /opt/etc/init.d/SXXxxx В каждом из них rc.func включается как часть кода. Делать его исполняемым не надо, точнее говоря, это ни на что не повлияет.

dlink
24-05-2012, 09:12
Спасибо за ответ, можно в целях развития вопрос - вот смотрю на скрипт S10cron и не вижу там включения rc.func:
S10cron

#!/bin/sh
#
# Startup script for cron

PIDFILE=/opt/var/run/cron.pid

case $1 in
start)
opt/sbin/cron
;;
stop)
[ -f ${PIDFILE} ] && kill `cat ${PIDFILE}` ;;
*)
echo "usage: $0 (start|stop)"
exit 1
esac

ryzhov_al
24-05-2012, 18:33
Спасибо за ответ, можно в целях развития вопрос - вот смотрю на скрипт S10cron и не вижу там включения rc.func:Да, так и есть. Иногда авторы самописных скриптов не доверяют имеющимся механизмам запуска, а иногда (изредка) просто невозможно «впихнуть» логику запуска какой-нибудь софтины в «канонический вид». В приложенном (http://wl500g.info/showthread.php?30086-%CF%EE%E4%EA%EB%FE%F7%E5%ED%E8%E5-%F0%E5%EF%EE%E7%E8%F2%E0%F0%E8%FF-Entware-%ED%E0-%EE%F0%E8%E3%E8%ED%E0%EB%FC%ED%EE%E9-%EF%F0%EE%F8%E8%E2%EA%E5-Asus-RT-N66U&p=250872#post250872) мной в соседней теме примере тот же cron запускается «каноническим» способом.