Пользователь
0,0
рейтинг
4 марта 2008 в 21:21

Администрирование → Как загружается Linux tutorial

Update: Статья и скрипты были обновлены в марте 2013 (прошло 5 лет, старые скрипты не сильно отличаются от текущих, но всё-таки лучше изучать актуальный код, а логика загрузки системы за эти годы немного изменилась — иначе работает udev, появились новые синтетические fs вроде devtmpfs, /var/run переехал в /run, etc.).

Когда я осваивал Linux, мне было очень интересно что происходит при загрузке системы. Попытка разобраться в процессе загрузки привела меня в исходники загрузочных скриптов (/etc/inittab, /etc/rc*, /etc/init.d/*, ...) и их конфигов (/etc/sysconfig/*, /etc/cond.f/*, ...). Надо отметить серьёзные размеры и сложность этих скриптов — чтобы в них разобраться потребовалось немало времени. Но я в те времена искренне верил, что загрузка это сложный процесс, и что размеры и сложность загрузочных скриптов вполне оправданы.

Когда меня окончательно достал RedHat (2001 год), я решил собрать свой дистрибутив на базе LFS. Для своего дистрибутива пришлось самостоятельно разрабатывать загрузочные скрипты, и тут-то выяснилась правда: ничего сложного в процессе загрузки нет!

Проработав 2.5 года на своём дистрибутиве (PoWeR Linux) я мигрировал на Gentoo (на качественную поддержку своего просто не хватало времени). Изучив загрузочные скрипты Gentoo я пришёл в ужас! Их размеры и сложность были ещё больше, чем у старого RedHat. После детального изучения стала ясна причина: один и тот же комплект загрузочных скриптов использовался и для LiveCD и для обычной системы — такой себе универсальный монстрик. Так что при переходе на Gentoo я решил взять загрузочные скрипты из PoWeR Linux а стандартные Gentoo-шные не использовать (т.е. у меня от Gentoo используется только portage). И с тех пор ещё 4 года эти скрипты работают у меня на домашней рабочей станции и кучке удалённых серверов.

Характеристики


Размер скриптов (всех вместе) — 308 строк, 8KB:
$ wc 1 3 lib.sh 
 201  769 5855 1
  78  272 1726 3
  29  118  771 lib.sh
 308 1159 8352 итого

Минусы:
  1. Всё в одном файле — при обновлении приложений практически невозможно автоматически обновить код инициализации этого приложения. Например, когда обновляется ALSA, то пакет может просто заменить файлы /etc/init.d/alsasound, /etc/conf.d/alsasound, /etc/modules.d/alsa. А в моём случае админу нужно будет ручками править /etc/runit/1.
  2. Нет поддержки всего на свете. Например, я не использую RAID и LVM — так что команды для их инициализации вам нужно будет добавлять самостоятельно.
  3. Вам нужно будет самостоятельно поддерживать эти скрипты. Я обычно при обновлении Gentoo поглядываю на изменения в (неиспользуемых мной) /etc/init.d/* скриптах и если меняется что-то важное — обновляю свои скрипты. Но, на практике, необходимость в таких изменениях возникает примерно раз в два года.

Плюсы:
  1. Всё в одном небольшом файле — нет необходимости разыскивать по куче скриптов и их конфигов где настраивается то, что вам понадобилось; можно быстро и легко увидеть все базовые настройки системы.
  2. Есть поддержка всего, что мне и моим друзьям за 11.5 лет было нужно на домашних компах и серверах.
  3. Идеальны для изучения процесса инициализации Linux. Вы работаете с реальными базовыми командами Linux, которые одинаковы во всех дистрибутивах, а не со скриптами и конфигами специфичными для вашего дистрибутива.
  4. Ускоряют загрузку системы. У меня домашняя машина грузится в single user mode (6 консолек с getty, syslog, klog, acpid, dnscache, tinydns, gpm) за 11 секунд. Я экспериментировал с параллельной загрузкой в стиле initng — эффект скорее отрицательный за счёт усложнения скриптов и порождения лишних процессов. Initng хорош для ускорения загрузки традиционных, раздутых скриптов, выполняющих множество ненужных действий, а в моём случае ускорять просто нечего. :)

Не смотря на малый размер эти скрипты не только надёжно и быстро грузят систему, но и поддерживают несколько фич облегчающих жизнь админу:
  • Выполняемые команды сгруппированы в блоки по типам. В процессе загрузки выводятся названия блоков, с информацией были ли ошибки при выполнении команд блока.
  • Если при выполнении блока команд были ошибки — выводится детальная информация по командам этого блока и возникшим ошибкам, после чего система ждёт 5 секунд нажатия любой кнопки для запуска bash и ручного исправления ошибок. После выхода из bash предлагается либо продолжить загрузку либо перегрузиться. Если ничего не нажимать, загрузка продолжится.
  • Логи всего, что выводится при загрузке и отключении на экран (названия блоков команд и информация по возникающим ошибкам) сохраняются в файлах /var/log/boot, /var/log/shutdown. Благодаря этому можно на удалённых серверах посмотреть, как проходила загрузка/отключение.


Пример сообщений выводимых при загрузке


 + UDEV
 + MODULES
 + SYSCTL
 + MTAB
 - MOUNTALL

++ swapon -a
++ false
EXIT CODE: 1
++ mount -at nocoda,nonfs,noproc,noncpfs,nosmbfs,noshm
... press any key in 5 seconds to open shell …
 + CLEANTMP
 + RANDOMSEED
 + HWCLOCK
 + SENSORS
 + LOADKEYS
 + SOUND
 + HOST_NAME
 + ENVUPDATE
 + NETWORK
 + RUNIT
 + DMESG



Runit


Для загрузки я вместо SysVinit использую Runit. Runit не поддерживает /etc/inittab, вместо этого в нём используется простая схема:
  1. При загрузке запускается скрипт /etc/runit/1. Его задача полностью проинициализировать систему.
  2. По завершению скрипта /etc/runit/1 запускается скрипт /etc/runit/2, который должен запустить все необходимые сервисы (syslog, getty, ssh, apache, ...).
  3. Когда пользователь останавливает/перегружает систему запускается скрипт /etc/runit/3 который должен подготовить систему к отключению (завершить все процессы, отмонтировать диски, etc.).

При желании можно настроить SysVinit для работы в том же стиле:

Запуск /etc/runit/{1,2,3} из SysVinit: /etc/inittab


id:3:initdefault:
rc::bootwait:/etc/runit/1
l0:0:wait:/bin/sh -c '/etc/runit/3; exec /sbin/halt'
l3:3:once:/etc/runit/2
l6:6:wait:/bin/sh -c '/etc/runit/3; exec /sbin/reboot'
ca:12345:ctrlaltdel:/sbin/shutdown -r now


Сервисы


Для запуска всех сервисов (getty, syslog, mysql, etc.) я использую тот же runit (по сути это просто немного улучшенный вариант daemontools). Но это отдельная большая тема, так что просто уточню что в этой статье скриптов для запуска сервисов нет, здесь только инициализация/отключение системы.

Исходники


Вспомогательные функции: /etc/runit/lib.sh


#!/bin/bash
startlog() { exec 3>&1 4>&2 1> >(tee $1) 2>&1; }
stoplog() { exec 1>&3- 2>&4-; }

wanna() {
    echo -e "\a... press any key in $2 seconds to $1 ..."
    read -t $2 -n 1 -s </dev/console
}
emergency() {
    if wanna "open shell" 5; then
        bash --norc </dev/console &>/dev/console
        if [[ "$0" == "/etc/runit/1" ]] && wanna "reboot now" 3; then
            exit 100
        fi
    fi
}

trace() { trap 'ERR=$?' ERR; set -Ex; $1 2>&1; set +Ex; trap ERR; } 2>&-
try() {
    local output=$( trace $1 )
    if [[ "$output" =~ "ERR=" ]]; then
        echo -e "\e[1m\e[31m - \e[37m$1\e[0m"
        echo "$output" | sed $'s/.*ERR=\(.*\)/\a\033[36mEXIT CODE: \\1\033[0m/g'
        emergency
    else
        echo -e "\e[1m\e[32m + \e[37m$1\e[0m"
    fi
}


Startup: /etc/runit/1


#!/bin/bash

CONSOLE() {
    dmesg -n 1
}

INIT() {
    mount -n -t proc -o "noexec,nosuid,nodev" none /proc
    mount -n -t sysfs -o "noexec,nosuid,nodev" none /sys
    mount -n -t tmpfs -o "mode=0755,nosuid,nodev" none /run
    mkdir /run/lock
    chmod 0775 /run/lock
    chown root:uucp /run/lock
    if grep -qs devtmpfs /proc/mounts; then
	mount -n -t devtmpfs -o "remount,exec,nosuid,mode=0755,size=10M" none /dev
    elif grep -qs devtmpfs /proc/filesystems; then
	mount -n -t devtmpfs -o "exec,nosuid,mode=0755,size=10M" none /dev
    else
	mount -n -t tmpfs none /dev
	busybox mdev -s
    fi
    # needed to run startlog (in /etc/runit/lib.sh) before UDEV
    ln -snf /proc/self/fd /dev/fd
    # extra mountpoints in /dev
    mkdir -p /dev/pts
    mount -n -t devpts -o "noexec,nosuid,gid=5,mode=0620" none /dev/pts
    mkdir -p /dev/shm
    mount -n -t tmpfs -o "noexec,nosuid,nodev" none /dev/shm
}

UDEV() {
    echo "" >/proc/sys/kernel/hotplug
    udevd --daemon
    udevadm trigger --type=subsystems --action=add
    udevadm trigger --type=devices --action=add
    udevadm settle --timeout=30
}

HWCLOCK() {
    hwclock --hctosys --localtime && touch /run/init.hwclock
}

MODULES() {
    true    # bash doesn't allow empty functions
#    modprobe -q nvidia NVreg_DeviceFileMode=432 NVreg_DeviceFileUID=0 NVreg_DeviceFileGID=27 NVreg_ModifyDeviceFiles=1
#    modprobe -q -a vmmon vmci vsock vmblock vmnet
#    modprobe -q -a vboxdrv vboxnetflt vboxnetadp
}

FSCK() {
    fsck -A -p -C0 -T -t noafs,nocifs,nocoda,nodavfs,nofuse,nofuse.sshfs,nogfs,noglusterfs,nolustre,noncpfs,nonfs,nonfs4,noocfs2,noshfs,nosmbfs,noopts=_netdev
}

REMOUNT() {
    mount -n -o remount,rw /
    grep -v ^rootfs /proc/mounts > /etc/mtab
    for i in $(cut -d ' ' -f 2 /etc/mtab | grep -vx /); do
    	mount -o remount "$i"
    done
}

LOCALMOUNT() {
    mount -at noproc,noafs,nocifs,nocoda,nodavfs,nofuse,nofuse.sshfs,nogfs,noglusterfs,nolustre,noncpfs,nonfs,nonfs4,noocfs2,noshfs,nosmbfs -O no_netdev
    swapon -a
}

SYSCTL() {
    sysctl -p /etc/sysctl.conf
}

MIGRATERUN() {
    rm -rf /var/lock
    ln -s /run/lock /var/lock
    rm -rf /var/run
    ln -s /run /var/run
}

UTMPWTMP() {
    > /var/run/utmp
    chgrp utmp /var/run/utmp
    chmod 0664 /var/run/utmp
    [ -e /var/log/wtmp ] || cp -a /var/run/utmp /var/log/wtmp
}

CLEANTMP() {
    rm -f  /tmp/.X*-lock /tmp/esrv* /tmp/kio* /tmp/jpsock.* /tmp/.fam*
    rm -rf /tmp/.esd* /tmp/orbit-* /tmp/ssh-* /tmp/ksocket-* /tmp/.*-unix
    mkdir -p /tmp/.{ICE,X11}-unix
    chmod 1777 /tmp/.{ICE,X11}-unix
}

RANDOMSEED() {
    mkdir -p /var/lib/misc
    [ -f /var/lib/misc/random-seed ] && cat /var/lib/misc/random-seed >/dev/urandom
    rm -f /var/lib/misc/random-seed
    local psz=$(( $(sysctl -n kernel.random.poolsize 2>/dev/null || echo 4096) / 4096 ))
    (umask 077; dd if=/dev/urandom of=/var/lib/misc/random-seed count=$psz 2>/dev/null)
}

SENSORS() {
    sensors -s
}

LOADKEYS() {
    # Commands for TTY initialization like 'setfont' and 'echo -ne "\033(K"'
    # shouldn't be executed in /etc/runit/1 because:
    # - which TTYs should be initialized may depend on current runlevel
    # - if TTY state become broken (for ex. after 'cat /dev/urandom'),
    #   then after logout and login TTY state should be reinitialized
    # these commands should be executed before each getty invocation instead.
    kbd_mode -u
    loadkeys koi2   # -q windowkeys
#    loadkeys -q -u ru4
    dumpkeys -c koi8-r | loadkeys --unicode
}

SOUND() {
    alsactl -f /etc/asound.state restore && touch /run/init.alsa
}

HOST_NAME() {
    # Here you should set only "host" part of your fqdn.
    # Add this line to /etc/hosts to configure FQDN:
    #   YOUR.IP.ADDR.ESS    YOUR_HOSTNAME.DOMAIN.TLD    YOUR_HOSTNAME
    hostname YOUR_HOSTNAME
}

NETWORK() {
    ip link set lo up
    iptables-restore </etc/iptables

    #ip link set eth0 up
    #ip addr add 192.168.1.2/24 dev eth0

    #ip route add default via 192.168.1.1 dev eth0
}

RUNIT() {
    # Set default action (shutdown or not) if Ctrl+Alt+Del pressed,
    # but /etc/runit/ctrlaltdel don't setup /etc/runit/stopit.
    touch /etc/runit/stopit
    chmod 100 /etc/runit/stopit
    
    # Set default action on shutdown (halt or reboot) if:
    # - /etc/runit/1 crash or exit 100
    # - /etc/runit/2 exit non 111
    # - Ctrl+Alt+Del pressed, but /etc/runit/ctrlaltdel don't setup /etc/runit/reboot
    touch /etc/runit/reboot
    chmod 100 /etc/runit/reboot
    
    # Set runlevel to:
    # - single      if kernel has param: S
    # - RUNLEVELNAME    if kernel has param: runlevel=RUNLEVELNAME
    # - default     if kernel has no params or unable to set requested runlevel
    grep -q '\(^\| \)S\( \|$\)' /proc/cmdline && runlevel='single'
    runsvchdir ${runlevel:-default} || runsvchdir default
}

SEND_MAIL() {
    echo -e "To: root\nSubject: reboot at $(date)" | sendmail -t
}

DMESG() {
    # Create an 'after-boot' dmesg log
    dmesg > /var/log/dmesg
    chmod 640 /var/log/dmesg
}


PATH=/sbin:/usr/sbin:/bin:/usr/bin
trap ':' INT QUIT TSTP
. /etc/runit/lib.sh

try CONSOLE
try INIT
startlog /run/boot.log
try UDEV
try HWCLOCK
#try MODULES    # Enable & configure this if you have modules support in kernel
    FSCK
try REMOUNT
try LOCALMOUNT
try SYSCTL
try MIGRATERUN
try UTMPWTMP
try CLEANTMP
try RANDOMSEED
#try SENSORS    # Enable this if you have configured lm_sensors
#try LOADKEYS   # Enable & configure this for non-english keyboard layout
#try SOUND      # Enable this if you have sound card (also in /etc/runit/3!)
try HOST_NAME   # Do not forget to configure this
try NETWORK     # Do not forget to configure this
try RUNIT
#try SEND_MAIL  # Enable this if you wanna receive notification email on reboot
try DMESG
stoplog
mv /run/boot.log /var/log/boot

# Select next stage (exit 0 for stage 2, exit 100 for stage 3):
exit 0


Shutdown: /etc/runit/3


#!/bin/bash

CONSOLE() {
    chvt 1
    # Required in case getty was last process in this console and it leave
    # console in broken state (\n work as <LF> without <CR>).
    { stty sane ; echo ; } >/dev/console
}

TERM() {
    # Give a chance for all processes for clean exit.
    # This also will kill all 'runsvdir' and signal all 'runsv' to exit.
    killall5 -15 || [ $? -eq 2 ]
}

HWCLOCK() {
    test -f /run/init.hwclock && hwclock --systohc --localtime --noadjfile
}

SERVICES() {
    sv force-stop /var/service/* &>/dev/null || :
}

SOUND() {
    test -f /run/init.alsa && alsactl -f /etc/asound.state store
}

RANDOMSEED() {
    local psz=$(( $(sysctl -n kernel.random.poolsize 2>/dev/null || echo 4096) / 4096 ))
    (umask 077; dd if=/dev/urandom of=/var/lib/misc/random-seed count=$psz 2>/dev/null)
}

NETWORK() {
    ip link set group default down
}

WTMP() {
    halt -w
}

KILL() {
    # Goodbye to everybody...
    killall5 -9 || [ $? -eq 2 ]
}

UMOUNT() {
    sync; sync
    # Unmounting loopback devices first:
    for d in $(grep '^/dev/loop' /proc/mounts | cut -d ' ' -f 2 | tac); do
        eval "umount -d -r -f $'$d'"
    done
    # Unmounting all real filesystems except root:
    for d in $(egrep -v '^\S+ (/|/dev|/dev/.*|/proc|/proc/.*|/run|/sys|/sys/.*) ' /proc/mounts | cut -d ' ' -f 2 | tac); do
        eval "umount -r -f $'$d'"
    done
    # Switching off swap
    umount -a -t tmpfs 2>/dev/null || :
    swapoff -a
}


PATH=/sbin:/usr/sbin:/bin:/usr/bin
trap ':' INT QUIT TSTP
. /etc/runit/lib.sh

try CONSOLE
startlog /var/log/shutdown
try TERM
try HWCLOCK
try SERVICES
#try SOUND      # Enable this if you have sound card
try RANDOMSEED
try NETWORK
try WTMP
try KILL
try UMOUNT
stoplog
Alex Efros @powerman
карма
302,5
рейтинг 0,0
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Реклама

Самое читаемое Администрирование

Комментарии (71)

  • 0
    sic!
  • +5
    класс. обожаю читать тонны исходников. это вы типа топик написали?
    • +8
      Угу. Это я типа и скрипты написал, и топик, и подход альтернативный к процессу продемонстрировал. А насчёт тонн исходников - понимаю Ваше возмущение, и даже разделяю, но... весь смысл этого топика как раз в том, чтобы предоставить новичкам довольно простой способ разобраться в процессе загрузки - а для этого нужно вычитать эти исходники, благо их объём и стиль написания делает это не сложным. Так что в данном случае исходники в топике полностью оправданы - они и есть основной контент и основная ценность в данном случае.
  • +3
    =\ мдя, тру линуксойд больше даже сказать нечего ... остается только завидовать и ковырять собственную генту.
    • +2
      Ой, блин, я-ж совсем забыл самое главное — DISCLAIMER! Народ, не повторяйте мои ошибки!! Сегодня вам просто любопытно разобраться в процессе загрузки, а завтра будете свои загрузочные скрипты ваять - оно вам надо? :-) :-) :-)
  • 0
    Тяжелая статья. Понимаю что материал не самый простой, но ведь статья видимо для тех, кто еще не разбирался в процессе загрузки? Я прочитал, и так ни черта и не понял
    • 0
      Вы меня, конечно, простите, но может быть, просто статья не для вас? Мне лично очень понравилось, с некоторыми добавками и изменениями я применил у себя. Плюс у автора в первых абзацах чёткая мотивация что и для чего он делает.
      • 0
        Ну раз я не ни черта не понял, то видимо действительно не для меня ) Но моё личное мнение, что можно было всё это подать гораздо доступней. Я не считаю что это статья для новичков.
        Если я возьмусь когда-нибудь изучить загрузку, обязательно напишу свою статью
    • НЛО прилетело и опубликовало эту надпись здесь
      • 0
        любой материал нужно подавать постепенно. в школе же не начинают в первом классе мат.анализ преподавать (хотят разобраться - разберутся :) ) Вот и здесь также
        Скорее всего меня ввело в заблуждение название статьи, подумалось что это для новичков. Хотя и автор в одном из комментов говорит что для новичков статья. Странно вобщем. Видимо я еще меньший новичок, чем те, для которых статья написана )
        • НЛО прилетело и опубликовало эту надпись здесь
          • 0
            "весь смысл этого топика как раз в том, чтобы предоставить новичкам довольно простой способ разобраться в процессе загрузки"
            Я - новичок. Статья - для новичков. Связь чувствуете?
            В моем посте не написано что матанализ не надо преподавать вобще. Надо. Но не в первом классе.
            • НЛО прилетело и опубликовало эту надпись здесь
              • 0
                "Видимо я еще меньший новичок, чем те, для которых статья написана"
                Надеюсь с третьего раза смысл моего поста до Вас дойдет
            • 0
              Ребята, давайте жить дружно. Для вас, не для вас - глупости это всё. Я тоже новичок, есть немало гораздо более продвинутых товарисчей. И вообще, чем больше знаешь, тем лучше понимаешь как много ты ещё не знаешь.

              Статья расчитана на "новичков", которые хотят разобраться в процессе загрузки Linux, но либо ниасилили чтение загрузочных скриптов своего дистрибутива, либо осилили но им этот процесс очень не понравился и цельной картины у них в голове не сложилось.
              • 0
                скилл линукса у меня ещё не настолько прокачан чтобы осилить статью ) Зато оформилось желание изучить загрузочные скрипты своего дебиана, а потом заново прочесть это, чтоб почерпнуть идеи об оптимизации процесса. Только тогда у меня появится чёткое представление о процессе загрузки. Т.е. будет с чем сравнивать
  • 0
    свасибо за проделаную работу. Обязательно ознакомлюсь на досуге.
  • +1
    Спасибо большое за труд.
    Возможно сам дорасту до подобных вещей, но пока это сильно круто для меня. :(
  • 0
    классно )))
    спасибо )))
    /etc/iptables
    лежит там где надо)
    будемс пробовать)
  • +2
    Исходники хороши и понятны. Хотя заголовок, наверное, должен был быть "Как загружается мой Linux".
    • 0
      Нет. Фокус в том, что загрузочные скрипты того же Gentoo выполняют абсолютно те же самые операции при загрузке, плюс кучу лишних действий. Я когда-то специально разработал жуткую штуку, которая встроилась в Gentoo-шные загрузочные скрипты, и вывела лог всего, что они реально делали при загрузке. Так вот, они делали на 95% то же самое. Только объём их не 316 строк, как у меня, а порядка 5000-8000 строк (всего там кода на 23500 строк, но он не весь используется при загрузке).
      • 0
        Не соглашусь. Чтобы знать "как загружается Linux", нужно, во-первых, иметь представление об организации железа и операционной системы, и, во-вторых, понимать процесс на уровне абстрактции boot loader -> linux -> init.

        А насчет инитскриптов - по-моему, имеет смысл разве что рассказать, что от них вообще нужно, и дать книжку про sh. И перед тем, как кому-то пригодится написание своих инитскриптов, ему пригодится знакомство с rc.d или sysvinit.

        Ввиду вышеизложенного считаю более правильным заголовок "как работает runit при загрузке моего Линукса" ;)
        • 0
          Вы привели неплохой пример разницы между поверхностным и фундаментальным образованием и пониманием.

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

          Не буду спорить относительно правильности заголовка, но с Вашим подходом к познанию системы я категорически не согласен — так только админов-эникейщиков воспитать можно.
          • 0
            Думаю, вы меня не так поняли.

            Речь не о том, что должен знать или уметь хороший админ - об админах и речи нигде не было.

            Я просто хотел сказать, что знание `subj` не исчерпывается тем, что описано в статье (с точки зрения админа - почти; разработчик ядра же, к примеру, ожидает совсем другой ответ), и нигде не указывал, чем оно исчерпывается.

            Моя критика относится не к статье, а к заголовку. Я также выразил свои соображения насчет подачи материала новичкам. Им не следует рассказывать, что загрузка linux - это инитскрипт. Может быть, кому-то будет легче понять, как они работают, исходя из предложенного кода, но и в таком случае поймут они это не здесь. И значительного упрощения процесса я здесь не вижу.

            Новичкам я бы все-таки рекомендовал вникнуть в rc.d тех же slackware (лучше документированных скриптов пока не видел) или arch.

            А подход runit интересный, спасибо за статью :)
  • 0
    > Например, я не использую RAID и LVM

    Странно, что такие вещи не используются на серверах.
    • 0
      Вы знаете, бывают разные случаи. Совать RAID и LVM везде по умолчанию - не самая классная идея. На моих проектах винт не является узким местом - всё сильно заоптимизированно и 98% инфы существует только в памяти.
      • 0
        Всё верно. Но винт является single point of failure.
        • 0
          У нас кластер. Выйдет из строя винт или сервер целиком - не очень критично (хотя не везде, кое-где SPoF у нас есть, не буду врать).
    • 0
      Хм. Под RAID здесь, нутром чую, имеется в виду Software RAID - который даже на сервере (а скорее, именно на сервере) не особо нужен. Да и LVM имеет смысл только тогда, когда нужно динамически менять таблицу разделов и производить тому подобные извращения. Что на сервере (да и на обычной машине) должно производиться максимально редко. Так что отсутствие RAID и LVM лично я считаю оправданным.
      А вообще, ставить такое для сервера.. С одной стороны, меньше кода - меньше места для ошибки. С другой стороны - код init-скриптов выверяли сотни человек - а этот код прочитают единицы. Но - интересно.
      • 0
        А что плохого в software raid для небрендовых сервером, скажем? Очень даже адекватное решение, на мой взгляд.
        Другое дело, какой-нибудь HP Management Server, который заранее предупредит, что винт скоро умрет, меняйте.
        Но в бюджетных случаях Software RAID себя очень даже оправдывает.
      • 0
        Я обычно предпочитаю sw raid железным решениям. Так что - кому очень, кому нет.
  • –3
    инфра-красноглазие...
    • 0
      Только что сбегал к зеркалу... фух, не, пока всё в порядке. Обычные пока. Но я над этим работаю. :)
      • 0
        вот правильно, что не видно. глаза красные не в видимом спектре, а в инфра-, который не виден.
  • 0
    Хоть бы мне не пришлось в этом всем копаться. Смотрю и страшно становится.
  • 0
    А как будет выглядеть аналог, скажем,
    /etc/init.d/squid reload
    ?
    • +3
      # sv t squid

      Но это не относится к загрузочным скриптам, это сервисы. Почитайте документацию на daemontools и runit, там много любопытного. Если коротко о главном — для каждого сервиса запущен отдельный процесс-супервизор, который при умирании сервиса гарантированно и моментально получает SIGCHLD и перезапускает сервис. Это избавляет от принципиально ненадёжной возьни с /var/run/*.pid-файликами.

      Если у Вас возник напрашивающийся вопрос, отвечаю: за супервизорами следит супервизор супервизоров. :) А за ним следит процесс N1. По сути этот супервизор супервизоров запускается через exec в файле /etc/runit/2, и его выход для процесса N1 означает что пора вызывать /etc/runit/3 и перегружаться. Так что за каждым распоследним сервисом бдит цепочка процессов вплоть до процесса N1! Ничего надёжнее сделать нельзя в принципе.
  • 0
    Статья полезная, интересно. Для облегченных заточенных систем подходит отлично. А у себя на десктопе я вижу 30с загрузку раз в несколько дней, поэтому лень даже шевелиться, единственное скоро перейду на baselayout2.
    • +2
      Да, ускорять загрузку смысла нет. Эти скрипты хороши для обучения, и для тех, кто старается избегать избыточно сложных систем — простые вещи работают надёжнее, и даже если unthinkable happens их намного проще понять и пофиксить. Лично для меня большим плюсом является то, что не надо разыскивать в странных местах какую переменную в какое значение выставить чтобы настроить нужную функциональность — можно пойти в один конкретный файл и подстучать обычные параметры стандартной утилиты.

      Если мне изредка приходится что-то править в стандартных дистрибутивах — это просто мука! Наворочено столько, что понять где что нужно прописать для, например, поднятия алиаса на интерфейс или хитрой настройки роутинга — приходится сначала grep-ом находить скрипты вызывающие ifconfig/route, смотреть какие переменные они им передают параметрами, потом искать в каких конфигах эти переменные объявляются, потом разбираться с форматом значений этих переменных (который далеко не всегда тривиален, т.к. они иногда пытаются с помощью одной переменной управлять разными вещами). К простоте очень быстро привыкаешь, и теряешь навык (и желание) работать с переусложнёнными обычными системами. :(
  • +1
    Очень, очень жаль, что Вы забросили поддержку своего дистрибутива. Вам бы, с такими идеями, наоборот, собрать команду и заняться его разработкой. ;-) Или написанием скрипта, который пересаживал бы пользователей на вашу схему загрузки =)
    Вообщем, решение очень на самом деле интересное, спасибо за статью.
  • +1
    Лучше бы автор описал все процессы во время загрузки, все равно его скрипты никто использовать не будет.
    • 0
      ну, не обобщайте :)
      Использую, и весьма активно.
      • 0
        Ладно, погорячился... Скажем так - мало кто ;) Просто хотелось об основах прочитать, матчасть вобщем.
        • +1
          Ммм. Основы :
          - на большинстве систем стартует бутлодер, который позволяет выбрать, с какого раздела и какое ядро грузить дальше. А также передать какие-нить параметры для ядра. Этого шага может не быть и ядро может быть прописано намертво.
          Читать например howto по Grub.
          - Начинает выполняться ядро. Инициализируется, инициализирует девайсы и тд.
          Хардкорный уровень. Читать например в Linux kernel Hacking или в исходниках ядра :)
          - после того, как ядро закончит инициализироваться (в процессе загрузки после фразы "Freeing kernel memory") грузится первый userspace процесс (процесс с pid 1) - по умолчанию /sbin/init. Все остальные процессы порождены (отфоркнуты) первым.
          - init запускает на выполнение инициализационные скрипты.
          - и вот начиная с этой точки у Алекса и расписано.

          Соответственно, у powerman и у меня bootloader - Grub. Ядро - linux. Как инит процесс используется runit.
          А дальше собсно скрипты :)
          • 0
            /me пошел читать сорцы ядра :-D
    • 0
      что автор хотел, то и написал; "процессы" пускай другие описывают, вот вы например .. заместо комментария :)
      • 0
        Если бы я знал... а так я интересуюсь. Просто тема называется "Как загружается Linux", почему бы тогда не назвать её "Как у меня загружается Linux"?
  • +1
    Хорошее чтиво!

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

    Когда начнет получаться с башем, эти скрипты покажуться простыми, как газетная статейка =), а уж когда консоль станет удобным и частым инструментом, то... =)

    Ничего страшного в скриптах и консоли нет.
    • +1
      Кстати, может Вам это покажется странным, но баш я знаю очень плохо. Просто опыт программирования большой, поэтому я довольно чётко представлял себе что мне нужно, и дальше мучал доку по башу пока не находил как это на нём делается. Соблазн написать всё это на perl был дичайший. :)
  • 0
    статья весьма познавательна для многих, но всё же попахивает некоторым хардкором. Я на своих пяти линуксовых инсталляциях (2 деба, арч, рхел и генту) не стал бы такого делать. Нет, я, в своё время, как и автор, заинтересовался процессом загрузки, разобрался, что и как, но писать свои сукрипты не стал, хотя бы потому, что если мои сервера придётся поддерживать кому-то другому, как он будет разбираться в нестандартном стартапе системы?
    • +1
      Есть такой момент. Но эти скрипты — лишь небольшая часть отличий моих систем от типовых дистрибутивов. У меня:
      • все сервисы работают под супервизорами (runsv из runit, аналог supervise из daemontools);
      • практически все логи (включая apache и mysql, которые для этого изначально вообще не приспособлены) ведутся через svlogd из runit (аналог multilog из daemontools);
      • в качестве syslog и klog используется socklog;
      • на каждом сервере поднят djbdns;
      • etc...
      Если учесть тот факт, что далеко не все знают про существование этих утилит, а работать с ними нормально умеет только часть тех, кто о них слышал...

      Получается, что умея неплохо админить какую-нить традиционный rpm-based дистрибутив, средний админ на моём сервере вообще ничего с ходу не поймёт: асболютно всё, к чему он привык делается совершенно иначе. Другие приложения-сервера, другой механизм работы с сервисами, другой принцип работы с логами... ну и старторые скрипты тоже другие. :) И самое главное - все эти утилиты принципиально отличаются от всего к чему он привык не только названием и параметрами, а идеологией, философией и подходом к решению проблем. Поэтому маны ему придётся курить достаточно долго, пока он в это въедет.

      Плохо ли это? Я так не думаю. На то есть целый ряд причин:
      1. Все эти отличия вызваны не скукой или желанием сделать никому не понятную систему. Такая система получается значительно более надёжной, безопасной, эффективной, лёгкой и простой. Стоит ли отказываться от этих преимуществ?
      2. Замена админа на NIX-сервере который настраивали после инсталляции — это всегда сложная операция. Новый админ будет ещё много месяцев наступать на разные грабли из-за неожиданных для него настроек сделанных предыдущим админом. (Бывают, конечно, исключения, когда все настройки либо хорошо задокументированны, либо все сервера типовые и настроены идентично.) Поэтому чаще всего на практике новый админ либо этот сервер старается не трогать, и в его настройки особо не вникать; либо переустанавливает систему с нуля.
      3. Разобраться с описанными мной утилитами и их философией очень полезно и способствует профессиональному росту админа. :)
      Основная причина, безусловно, первая. IMHO лучше новому админу научиться работать с такими, более совершенными системами, чем соглашаться на использование типовых систем с кучей недостатков исключительно ради того, чтобы всё было привычно и не нужно было ничего учить.
  • +1
    Лучшее — враг хорошего.

    Да, RHEL на мой взгляд (да и не только на мой) — не самая удачная система, но она стандарт, как это ни печально. И oracle тот же поддерживает только её в качестве варианта линуксовой системы. Да и хозяева серверов, как правило, с большим подозрением относятся к новым системам, потому что как бы хороша и идеологически верна новая система ни была - её надо поддерживать, а такую инсталляцию поддержать (т.е. разобраться с ней) сможет далеко не каждый, и не потому что система запредельно сложна или нестандартна, а потому что просто людей с головой мало в отрасли.

    Поэтому же, кстати, и пишется софт не пойми на чём, точнее, понятно на чём — пхп, цпп, ява. Потому что чем писать всё впятеро меньшей командой за вдесятеро меньшие сроки на коммон лисп скажем, люди предпочитают использовать те технологии, которые доступны широкой массе, чтобы случае чего было возможно найти человека который хоть что-то понимает в написаном.

    Заказчики, кстати, придерживаются примерно такой же идеологии, им не нужны более совершенные в технологическом плане, но отходящие от industry standards решения.

    А система ваша да, интересная. Вы её куда-нибудь выкладывали? Я бы покрутил, посмотрел, что и как.
  • +6
    Статью целиком разобрать не смог, но по случаю вспоминается шутка (мой вольный перевод):
    Когда я был новичком, то я брал ядро из коробки, потому что оно стабильно и работает. Когда я стал опытным, то я стал собирать свои ядра, потому что хотел заставить их работать так, как нужно было мне. Когда я стал гуру, то я брал ядро из коробки, потому что оно стабильно и работает.

    Ничего личного ;)
  • 0
    Wow! Вы действительно powerman. :-)
  • 0
    Спасибо. Все собираюсь собрать дома медиацентр под Linux. Как раз по теме, т.к. сильно волнует быстрая загрузка.
  • 0
    Не понимаю, чем вам не понравились скрипты Gentoo и идея разработчиков с rc-update. У меня например Gentoo бутится до X'ов примерно за минуту. Какой смысл в выйгрыше в 10 секунд?
    • 0
      Какие 10 секунд? Даже выпонение всех 5000 строк скриптов займёт меньше секунды. Время загрузки определяется не навёрнутостью скриптов, а тем, что они загружают.

      Не совсем понятен смысл всей этой мегамонстряческой работы, проделанной автором. Выйгрыш в скорости загрузки не заметен невооружённым взглядом. Кто хочет понять механизм загрузки системы - читает доки по дистрибутиву. В результате данной работы автор получил кучу хардкода безо всех удобных фич, предоставляемых скриптами дистров.
      • 0
        Сборка дистрибутива по книге LFS - это куча экспириенса и собственный дистрибутив, от которого в дальнейшем можно получить удовольствие, когда будеш его допиливать его на пути к идеалу.

        Впрочем это только для повернутых гиков вроде меня и судя по всему топикстартера )) Убунтуюзерам это ненадо.
  • 0
    Как раз изучая Linux, перешёл от Ubuntu к ArchLinux (там минималистические сценарии загрузки, в них новичку гораздо легче разобраться). Но эти ещё круче! Очевидно, это будет следующая ступень.
  • +1
    Cool! Спасибо за статью! Побольше бы таких. Именно вглубь, а не бла-бла-бла в стиле "как тыкать в gimp и wine". :)
  • 0
    Радует что на хабре затрагивают такие темы. Только инит у тебя не идеальный, покрайней мере скорость непорадовала ;)
    У меня дома сервер с приличным количеством демонов быстрее загружается, а лаптоп так вобще ;)
    • 0
      зы инит арчлинуксовый, я просто убрал из него все лишнее. Распаралеливание в нем тоже есть =)
      • 0
        И ты здесь? (с) dimaka :-D Удобней арчевского я нигде пока не встречал, да и не хочу.
  • 0
    насколько быстрее получается по сравнению с генту?
    (хотя вас это кажется ообо и не интересует)
    мои линуксы секунд по 30-то всяко грузятся..
  • 0
    Чего то вот читаю, читаю...что-то знакомое...
    Мне кажется, или runit пытается скопировать bsd-style систему инициализации?
    А BSD-style это не быстрее и не легче, случаем?
    Возвращаемся обратно (т.е. новое это хорошо забытое старое?:) )
    Ни разу не пользовался runit, но последние 2 года пользуюсь ArchLinux'ом. Очень похоже...
  • НЛО прилетело и опубликовало эту надпись здесь
  • 0
    Ужас просто.

    По сравнению с Linux система FreeBSD похожа на DOS: после форматирования флэшки в UFS2 и внедрения загрузчика boot0 в "загрузочный сектор" систему можно просто скопировать с винчестера на эту флэшку, поправить /etc/fstab и дописать всего одну(!) строчку в /boot/loader.conf.
  • 0
    Разобраться, как загружается система это и полезно и очень интересно. Но писать свои скрипты, как и использовать чужие я не стал бы, ибо их необходимо самому поддерживать. Пример с ALSA весьма показателен. Отказ от SysVInit мне не понятен. /etc/inittab весьма удобен.
    В данном случае стандарт лучше, разработчики дистрибутива скорее лучше чем вы напишут надежную и более универсальную вещь, а если ошибка и обнаружится, то оперативно ее исправят.
  • 0
    Это всё происки консерватизма. Не обращайте внимания - пионерская дорога всегда была трудна. Побольше надо таких статей. Дело не в отказе от стандартов; товарисч проявил творческую инициативу, более того - поделился с массами в лучших традициях OS. А насчёт нестандартности и смены персонала серверов - 50% систем, которые я наблюдал, внушали мне трагический ужас множественными костылями и подпорками; причём всё внедряется на протяжении, как правило, нескольких лет, и уже сам автор не может понять, что происходит у него в системе. Это говорит о культуре и принципах администрирования. Никакой документации, никаких комментариев, не говоря уже о diff-файлах (или просто исходниках). И частенько всё заканчивается плавным выводом машины из калашного ряда на задворки истории...
    Обязательно внедрю к себе запчасти от вашей схемы.
    • 0
      Если будете внедрять - берите свежую полную версию у меня на сайте. В статье хоть и реальный код, но это всё-таки пример для обучения/демонстрации, и некоторых частей в статье нет (например, скрипта для shutdown, etc.).
  • 0
    Обновил статью/скрипты. Не уверен, нужно ли это кому-нибудь, но пусть лучше будет актуальная версия. В Gentoo эти скрипты можно поставить из оверлея «powerman» пакетом power-misc/runit-scripts.
  • Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.