22 марта 2015 в 16:14

Разбираемся с загрузкой ArchLinux по сети tutorial

В предыдущей статье мы подготовили базовую систему. Закончим настройку в следующей статье.

Здесь мы создадим новую систему Arch Linux, способную загружаться по сети и автоматически запускать браузер Firefox, а между делом разберёмся с необходимой функциональностью загрузочного сервера. Потом настроим сам сервер и попробуем с него загрузиться. Всё произойдёт в точности, как на картинке, которую нашёл гугл по запросу «PXE»:




Снова устанавливаем Linux



Archlinux выгодно отличается от готовых дистрибутивов тем, что установка новой системы из рабочей машины осуществляется точно так же, как при использовании установочного образа, и в обоих случаях вы получаете самую актуальную на данный момент версию системы. Понадобятся лишь небольшие установочные скрипты:
pacman -S arch-install-scripts


Совершенно предсказуемое начало:
export root=/srv/nfs/diskless
mkdir -p $root


Установим только базовые пакеты, поэтому:
pacstrap -d -c -i $root base

Примечание:
«Мы стремимся к максимальному уменьшению объёма установленной системы, т.  к. производительность сети намного ниже производительности самого медленного жёсткого диска!» — должен был написать я на этом месте, но я знаю, что объем можно уменьшить ещё сильнее, если выбрать конкретные пакеты из группы пакетов base. Предлагаю проделать это самостоятельно.


Далее повторите все действия вплоть до установки загрузчика согласно предыдущей статье. Вот чек-лист:
  • проведите русификацию (интернационализацию);
  • укажите часовой пояс и настройте автозапуск службы NTP;
  • добавьте пользователя username и заблокируйте его пароль от изменения.


Сравним загрузку с диска и загрузку по сети



В предыдущей статье мы рассматривали процесс загрузки Linux с точки зрения внутреннего накопителя. Сейчас мы представим происходящее глазами сетевой карты. Картинка из заголовка хорошо иллюстрирует события за исключением того, что все серверы в нашем случае будут работать на одном компьютере.

Сразу после включения компьютера, срабатывает код PXE (Preboot eXecution Environment, произносится пикси — спасибо вики), разместившийся непосредственно в ПЗУ сетевой карты. Его задача — найти загрузчик и передать ему управление.
Примечание:
Здесь и далее рассматриваются возможности сетевой карты, которая встроена практически в любую доступную в продаже материнскую плату (правда, среди некоторых, оборудованных ещё Socket 775, попадались немощные экземпляры). Если соответствующий PXE пункт отсутствует в списке загружаемых устройств BIOS, то попробуйте его включить в разделе интегрированных устройств среди настроек сетевой карты. Если ничего не помогает, то прочитайте инструкцию от своей материнской платы, и убедитесь, что она подходит для дальнейших экспериментов.


Сетевой адаптер совершенно не представляет в какой сети сейчас находится, поэтому назначает себе адрес 0.0.0.0 и отправляет сообщение DHCPDISCOVER. К сообщению прикреплются паспортные данные, которые обязательно нам пригодятся:
  • ARCH Option 93 — архитектура PXE клиента (UEFI, BIOS);
  • Vendor-Class Option 60 — идентификатор, который у всех PXE клиентов имеет вид «PXEClient:Arch:xxxxx:UNDI:yyyzzz», где цифры xxxxx – архитектура клиента, yyyzzz – мажорная и минорная версии драйвера UNDI (Universal Network Driver Interface).


Адаптер ожидает получить ответ от DHCP сервера по протоколу BOOTP (Bootstrap Protocol), где помимо нужного IP адреса, маски подсети и адреса шлюза, присутствует информация об адресе TFTP-сервера и названии файла загрузчика, который с него следует забрать. Сервер TFTP, в свою очередь, просто отдаёт любому желающему любые файлы, которые у него попросят.

После получения ответа и применения сетевых настроек, дальнейшее управление загрузкой передаётся полученному файлу, размер которого не может превышать 32 кБ, поэтому используется двухстадийная загрузка. Всё необходимое для отображения на экране загрузочного меню докачивается следом по тому же протоколу TFTP. Подавляющее большинство руководств по сетевой загрузке использует загрузчик pxelinux, но GRUB умеет то же самое, и даже больше: в нём есть разные загрузчики для разных архитектур, включая UEFI.

Далее загрузка приостанавливается на время отображения загрузочного меню, а потом по тому же протоколу TFTP докачиваются выбранные файлы vmlinuz и initramfs, которым передается дальнейшее управление загрузкой. На этом этапе уже нет вообще никакой разницы в механизме загрузки по сети или с внутреннего накопителя.

Настраиваем загрузку по сети с помощью GRUB



Поскольку GRUB на нашем сервере уже есть, создадим с его помощью структуру папок для сетевого клиента вот таким образом:

grub-mknetdir --net-directory=$root/boot --subdir=grub


В папке $root/boot появится папка grub и несколько других. Эту файловую структуру мы будем целиком «отдавать» с помощью TFTP-сервера. Сейчас мы используем 64-битный ArchLinux по той причине, что в 32-битной системе нет папки /grub/x86_64-efi/, которая требуется для загрузки систем UEFI. Можно взять эту папку с нашего 64-битного сервера и в неизменном виде перенести на 32-битный сервер, тогда в нём также появится поддержка UEFI.

Создайте файл конфигурации загрузчика со следующим содержимым:
cat $root/boot/grub/grub.cfg
function load_video {
    if [ x$feature_all_video_module = xy ]; then
        insmod all_video
    else
        insmod efi_gop
        insmod efi_uga
        insmod ieee1275_fb
        insmod vbe
        insmod vga
        insmod video_bochs
        insmod video_cirrus
  fi
}

if [ x$feature_default_font_path = xy ] ; then
    font=unicode
else
    font="fonts/unicode.pf2"
fi

if loadfont $font ; then
    set gfxmode=auto
    load_video
    insmod gfxterm
    set locale_dir=locale
    set lang=ru_RU
    insmod gettext
fi

terminal_input console
terminal_output gfxterm

set timeout=5
set default=0

menuentry "Автозапуск Firefox" {
    load_video
    set gfxpayload=keep
    insmod gzio
    echo "Загружается ядро..."
    linux /vmlinuz-linux \
         add_efi_memmap \
         ip="$net_default_ip":"$net_default_server":192.168.1.1:255.255.255.0::eth0:none \
         nfsroot=${net_default_server}:/diskless
    echo "Загружается инициирующая файловая система..."
    initrd /initramfs-linux.img
}



Я взял файл grub.cfg с сервера и убрал из него всё то, что не участвует в отображении загрузочного меню GRUB или как-то связано с дисками.

Обратите внимание на знакомую нам строку с параметрами ядра:
linux /vmlinuz-linux add_efi_memmap ip="$net_default_ip":"$net_default_server":192.168.1.1:255.255.255.0::eth0:none nfsroot=${net_default_server}:/diskless

Как и в предыдущий раз присваиваем значение переменной «ip». Напоминаю, что она используется в обработчике «net», который мы приспособили для настройки сетевой карты в загрузочном сервере. Здесь снова указывается статический IP адрес и постоянное имя сетевой карты eth0. Значения $net_default_ip и $net_default_server подставляются GRUB самостоятельно на основании данных, полученных из самого первого DHCP запроса. $net_default_ip – это выделенный для нашей машины IP адрес, а $net_default_server — IP адрес загрузочного сервера.

Большинство руководств по сетевой загрузке (среди обнаруженных на просторах рунета), предлагают устанавливать переменную так «ip=::::::eth0:dhcp», что вынуждает обработчик net отправлять новый запрос DHCPDISCOVER для повторного получения сетевых настроек.

Нет объективной причины лишний раз «спамить» DHCP-сервер и ждать, пока он откликнется, поэтому снова используем статику и не забываем указать DNS-серверы. Такую задачу мы уже решали, поэтому просто копируем нужные файлы и добавляем службу в автозагрузку:
cp {,$root}/etc/systemd/system/update_dns@.service && cp {,$root}/etc/default/dns@eth0 && arch-chroot $root systemctl enable update_dns@eth0


Возвращаемся к строке с параметрами ядра. Ещё незнакомая нам команда add_efi_memmap (EFI memory map) добавляет EFI memory map доступной RAM. В прошлый раз мы её намеренно пропустили, из-за сравнительно сложной предварительной разметки носителя для поддержки UEFI. Сейчас нам ничего размечать не нужно, потому что файловая система на загрузочном сервере уже существует и будет использоваться в неизменном виде.

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

Подготавливаем initramfs



За подключение корневой файловой системы по протоколу NFS отвечает обработчик net. В прошлый раз мы убирали из него эту функциональность, но сейчас она нам понадобится, правда, в немного доработанном виде. Дело в том, что обработчик net из коробки поддерживает подключение только по протоколу NFS версии 3. К счастью, поддержка 4-й версии добавляется очень просто.

Сначала установим пакет, в который входит нужный нам обработчик net, а также пакет утилит для работы с NFS (модуль nfsv4 и программа mount.nfs4):

pacman --root $root --dbpath $root/var/lib/pacman -S mkinitcpio-nfs-utils nfs-utils


Исправим обработчик net из папки hooks (вместо команды для монтирования nfsmount, теперь будем использовать mount.nfs4):
sed s/nfsmount/mount.nfs4/ "$root/usr/lib/initcpio/hooks/net" > "$root/etc/initcpio/hooks/net_nfs4"

С помощью установщика обработчика из папки install добавим модуль nfsv4 и программу mount.nfsv4 в iniramfs. Сначала копируем и переименовываем заготовку:
cp $root/usr/lib/initcpio/install/net $root/etc/initcpio/install/net_nfs4

Теперь исправляем только одну функцию build(), а всё остальное не трогаем:
nano $root/etc/initcpio/install/net_nfs4

build() {
    add_checked_modules '/drivers/net/'
    add_module nfsv4?

    add_binary "/usr/lib/initcpio/ipconfig" "/bin/ipconfig"
    add_binary "/usr/bin/mount.nfs4" "/bin/mount.nfs4"

    add_runscript
}


Добавляем обработчик в initramfs путём исправления строки в файле mkinitcpio.conf:
nano $root/etc/mkinitcpio.conf

HOOKS="base udev net_nfs4"


Если ничего не трогать, то обычно для сжатия файла initramfs используется быстрый архиватор gzip. Мы не настолько торопимся, насколько хотим компрессию посильнее, поэтому воспользуемся xz. Снимаем комментарий с этой строки в файле mkinitcpio.conf:
COMPRESSION="xz"


Архивация xz происходит значительно дольше, но файл initramfs при этом уменьшается минимум в пару раз, из-за чего гораздо быстрее передается TFTP сервером по сети. Копируем пресет с нашего сервера, чтобы в ходе работы генерировался только один файл initramfs, после чего запускаем mkinitcpio:

cp /etc/mkinitcpio.d/habr.preset $root/etc/mkinitcpio.d/habr.preset && arch-chroot $root mkinitcpio -p habr


Напоследок отредактируем fstab. Здесь можно подобрать опции монтирования корневой файловой системы, чтобы оптимизировать её работу, но мы ничего трогать не будем:
echo "192.168.1.100:/diskless / nfs defaults 0 0" >> $root/etc/fstab


Базовая установка клиентской системы на этом закончена. Но мы хотим добавить графическое окружение и автоматический запуск Firefox.

Загружаемся в Firefox



Для уменьшения объема памяти, занимаемого нашей системой, мы откажемся от использования экранного менеджера и остановимся на простейшем оконном менеджере, например, openbox с автоматической авторизацией пользователя username. Использование «облегченных» компонентов позволит системе замечательно запускаться и работать даже на самом древнем железе.

Установим модули для поддержки VirtualBox, сервер X, симпатичный TTF-шрифт, openbox и firefox (все остальные модули будут установлены как зависимости):
pacman --root $root --dbpath $root/var/lib/pacman -S virtualbox-guest-modules virtualbox-guest-utils xorg-xinit ttf-dejavu openbox firefox


Включаем автозагрузку службы virtualbox:
arch-chroot $root systemctl enable vboxservice


Добавим автоматический вход пользователя username без ввода пароля, для этого изменим строку запуска agetty:
mkdir $root/etc/systemd/system/getty@tty1.service.d && \
echo -e "[Service]\nExecStart=\nExecStart=-/usr/bin/agetty --autologin username --noclear %I  38400 linux Type=simple %I" > $root/etc/systemd/system/getty@tty1.service.d/autologin.conf


Сразу же после авторизации пользователя выполняется файл ~/.bash_profile, из его домашней папки, куда мы добавляем автоматический запуск графического сервера:
echo '[[ -z $DISPLAY && $XDG_VTNR -eq 1 ]] && exec startx &> /dev/null' >> $root/home/username/.bash_profile


За запуском X-сервера должен стартовать openbox:
cp $root/etc/X11/xinit/xinitrc $root/home/username/.xinitrc && echo 'exec openbox-session' >> $root/home/username/.xinitrc

Закомментируйте следующие строки в самом конце файла (от строки twm до добавленной нами строки с запуском openbox, но не включая её):
cat $root/home/username/.xinitrc

# twm &
# xclock -geometry 50x50-1+1 &
# xterm -geometry 80x50+494+51 &
# xterm -geometry 80x20+494-0 &
# exec xterm -geometry 80x66+0+0 -name login
exec openbox-session


Копируем конфигурационные файлы openbox
mkdir -p $root/home/username/.config/openbox && cp -R $root/etc/xdg/openbox/* $root/home/username/.config/openbox


Добавляем firefox в автозагрузку в окружении openbox:
echo -e 'exec firefox habrahabr.ru/post/253573/' >> $root/home/username/.config/openbox/autostart


Поскольку мы только что от имени суперпользователя хозяйничали в домашней папке пользователя username, нам нужно вернуть ему права на все файлы, расположенные в его папке:
chown -R username $root/home/username


Подготовка системы к загрузке по сети закончена, и настала пора переходить к настройке загрузочного сервера. Теперь мы знаем, что для загрузки нам понадобятся:
  • DHCP-сервер с поддержкой протокола BOOTP для настройки сетевой карты;
  • TFTP-сервер для передачи загрузчика и файлов vmlinuz и initramfs, которые у нас находятся в папке $root/boot/grub;
  • NFS-сервер для размещения корневой файловой системы, которая лежит у нас в папке $root.


Настраиваем загрузочный сервер



Дальнейшие шаги с небольшими изменениями повторяют эту статью из вики, поэтому минимум комментариев с моей стороны.

Устанавливаем DHCP сервер


Скачиваем пакет:
pacman -S dhcp

и приводим содержимое конфигурационного файла /etc/dhcpd.conf к следующему виду:
mv /etc/dhcpd.conf /etc/dhcpd.conf.old 

nano /etc/dhcpd.conf

# Разрешаем использование протокола BOOTP
allow booting;
allow bootp;

# Утверждаем, что сервер является авторитетным (обычно роутеры либо не авторитетны, либо BOOTP не поддерживают, поэтому их PXE слушать не будет)
authoritative;

# получаем архитектуру клиента (это обсуждалось выше)
option architecture code 93 = unsigned integer 16;

# работаем в такой подсети (исправляйте под себя)
subnet 192.168.1.0 netmask 255.255.255.0 {

# в этот класс попадут все те, кто пытается загружаться
class "pxe_client" {
match if exists architecture;
}

pool {
# Разным архитектурам отдаём разные файлы:
if option architecture = 7 {
filename "/grub/x86_64-efi/core.efi";
} else {
filename "/grub/i386-pc/core.0";
}

# Рекомендую указать адрес TFTP сервера, несмотря на то, что это необязательно, раз он там же, где DHCP
next-server 192.168.1.100;

# Здесь, как обычно (не забывайте исправлять под себя)
default-lease-time 600;
max-lease-time 7200;
option domain-name-servers 192.168.1.1;
option routers 192.168.1.1;
range 192.168.1.128 192.168.1.192;

# Обрабатываем запросы только тех, кто загружается
allow members of "pxe_client";
}

}



Как видите, DHCP-сервер будет отвечать только на те запросы DHCPDISCOVER, которые придут от PXE клиентов, а остальные просто проигнорируются.

Запускаем DHCP сервер:
systemctl start dhcpd4


Устанавливаем TFTP сервер


Скачиваем и устанавливаем необходимый пакет:
pacman -S tftp-hpa

Нам нужно, чтобы TFTP сервер предоставлял доступ к файлам загрузчика, которые мы разместили в папке $root/boot. Для этого модифицируем запуск службы уже проверенным способом:
mkdir -p /etc/systemd/system/tftpd.service.d && echo -e '[Service]\nExecStart=\nExecStart=/usr/bin/in.tftpd -s /srv/nfs/diskless/boot' > /etc/systemd/system/tftpd.service.d/directory.conf

Первая строка «ExecStart=» отменяет выполнение команды, указанной в оригинальном файле $root/usr/lib/systemd/system/tftpd.service, а вместо нее выполняется "/usr/bin/in.tftpd -s /srv/nfs/diskless/boot". Только в том случае, когда служба запускается однократно (Type=oneshot), мы можем использовать несколько строк ExecStart= чтобы выполнять команды одну за другой. Это не тот случай, поэтому отменяем одну команду и выполняем другую.

Запускаем TFTP сервер:
systemctl start tftpd.socket tftpd.service


Устанавливаем NFS сервер



Скачиваем пакет:
pacman -S nfs-utils

Добавляем папку, в которую мы установили систему, в список экспортируемых:
echo -e "/srv/nfs 192.168.1.0/24(rw,fsid=root,no_subtree_check,no_root_squash)\n$root 192.168.1.0/24(rw,no_subtree_check,no_root_squash)" >> /etc/exports

Не забываем использовать синтаксис NFS v.4 указывая путь относительно папки с fsid=root (корневой по отношению ко всем остальным экспортируемым папкам, без указания которой ничего работать не будет).

Запускаем службы, обеспечивающие работу NFS-сервера:
systemctl start rpcbind nfs-server


На этом загрузочный сервер готов к работе.

Пробуем загрузиться по сети



Проследим за процессом загрузки с сервера с помощью программы tcpdump
pacman -S tcpdump

tcpdump -v '( \
    src host 0.0.0.0 and udp[247:4] = 0x63350101) or ( \
    dst host HabraBoot and dst port tftp) or ( \
    dst host HabraBoot and tcp[tcpflags] == tcp-syn)'


Первая строка «ловит» запрос DHCPDISCOVER от PXE клиента. В выводе, отфильтрованном второй строкой, будут перечислены имена всех файлов, запрашиваемых по TFTP. Третья строка показывает два tcp-syn запроса, отправляемых в самом начале подключения по протоколу NFS (первое соединение осуществляется обработчиком net, а второе переподключение происходит во время обработки файла fstab).

Создаём новую виртуальную машину, для краткости будем называть её «клиент». В настройках сети снова указываем тип подключения «Сетевой мост» и включаем машину. Сразу же нажимаем клавишу F12 на клавиатуре для выбора загрузочного устройства, а потом клавишу l, чтобы загрузиться по сети.

Дождитесь окончания загрузки. Если всё в порядке, то на сервере добавляем используемые службы в автозагрузку:

systemctl enable tftpd.socket tftpd.service dhcpd4 rpcbind nfs-server


Все серверы DHCP, TFTP и NFS мы запустили на одном загрузочном сервере. Делать так необязательно. Например, роутеры Mikrotik поддерживают Bootp и позволяют использовать себя в качестве TFTP — просто закачайте туда все нужные файлы и проверьте сетевые настройки.

Сейчас графическое окружение будет работать только в VirtualBox, потому что мы не устанавливали драйверы для «железных» видеокарт. Мы решим проблему автоматического подбора нужных драйверов в следующей статье. Заодно ускорим загрузку системы и сделаем из неё «живой образ».
Илья Назаров @Roshalsky
карма
20,0
рейтинг 0,0
Пользователь
Похожие публикации
Самое читаемое Администрирование

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

  • 0
    Эта вторая часть поинтереснее, да.

    откажемся от использования оконного менеджера и остановимся на простейшем окружении рабочего стола — openbox
    openbox это и есть типичнейший оконный менеджер.
    • 0
      Это так.

      Вынужден был представить его только в качестве создателя окружения рабочего стола. Здесь мы работаем без менеджера как такового, а сразу авторизуемся под именем конкретного пользователя и запускаем исключительно openbox. Он маленький и умеет всё, что нужно. Возможно, вы посоветуете более лёгкое окружение рабочего стола, которое сможет нарисовать окошки, иконки и экранные клавиатуры?
      • +2
        Вам же сказали, Openbox — оконный менеждер (window manager), а не окружение рабочего стола (desktop environment).
        • 0
          Всё исправлено, благодарю за замечание. Почему-то display manager я назвал словом window manager, и понеслось…
          • 0
            Display manager это программы-логинеры и стартеры сессий. KDM, SLiM, GDM.
            • 0
              Да, спасибо! Именно их я в начале почему-то назвал window manager, когда утверждал, что он нам не нужен.
  • 0
    Сколько времени занимает загрузка по 100 Мбит сети на реальном железе?
    • 0
      В текущем воплощении VirtualBox загружается за 45-50 секунд. Железо, думаю, около 2-х минут.

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

      Время инициализации BIOS до начала работы PXE — это 15-20 секунд (с UEFI вроде бы было быстрее).

      16:27:44.735923 отправка DHCPDISCOVER
      16:27:46.880359 подключение к TFTP
      16:28:12.520943 подключение корневой файловой системы
      16:28:16.514296 окончена авторизация пользователя
      Этот этап занимает примерно 32 секунды и за это время проходит около 110 MiB трафика.

      Сюда нужно добавить время на инициализацию графической оболочки и запуск Firefox — ещё секунд 10-20.

      Одновременно можно будет загружать 3-4 компьютера по 100 Мбит сети без заметной потери скорости загрузки.
      • 0
        А ведь если пускать это все по 1Gbit каналу с SSD диска, то вполне неплохо можно так десяток тонких клиентов запускать, всмысле бездисковые машины.
        • +1
          1 Gbit канал только ускорит время загрузки, да обычный жёсткий диск справится с забиванием такого канала под завязку. Часто нет необходимости загружать десятки машин одновременно. Можно загрузить пару-тройку, затем следующую группу и так далее. 100 Мбит сеть выдержит рассматриваемый сценарий использования даже с 50 одновременно работающими бездисковыми клиентами.

          Фокус в том, что загрузка производится только один раз, и именно в этот момент по сети гуляет наибольший трафик (причём есть подозрение, что TFTP-сервер даже 100 Мбит сеть не может раскачать до максимума). Во время обычной работы, если корневой раздел подключен через NFS, нагрузка на сеть небольшая, т. к. большая часть данных всегда находится в оперативной памяти. В следующей статье я покажу способ помещения «живого» образа в оперативную память целиком, тогда нагрузки на сервер во время работы не будет совсем. Теоретическое количество одновременно работающих бездисковых клиентов, загруженных с одного сервера, приблизится таким образом к бесконечности. Думаю, что получится ужать систему из этой статьи мегабайт до 250-300, так что 1 Гб оперативки для нормальной работы без серверов и дисков будет вполне достаточно.
          • 0
            tftp — медленный.
            Попробуйте отдавать образ не по tftp, а по http.
            У нас образ в 250 мб отдается в считанные секунды. В качестве загрузчика сейчас использую ipxe, pxelinux вроде тоже так успеет
            • 0
              http требует больше ресурсов (не говоря о периодическом обновлении). Для тупого терминала (дисплей с клавой) не совсем подходит. Проще тогда держать систему на чипе.
  • 0
    Archlinux выгодно отличается от готовых дистрибутивов тем, что для его установки куда-то ещё не нужно иметь установочный диск.

    Почему же. Например Debian (и походные) без проблем устанавливаются через debootstrap. У других дистрибутивов, я уверен, существуют схожие решения.
    • 0
      Спасибо за замечание. Я просто хотел акцентировать внимание на том, что Archlinux устанавливается даже с установочной флешки тем же самым способом (bootstrap). Сейчас переформулирую фразу в статье.
      • 0
        Флешка с установочным образом Арча это одна из самых полезных в хозяйстве вещей. Выручала неоднократно после эксперементов с рабочими машинами (те машины на Убунте/Дебиане).
  • +2
    Я просто оставлю ссылку на Компьютерный клуб. Может быть будет интересно.
    80 машин с загрузкой по сети.
    Gentoo+wine
    www.youtube.com/watch?v=Sdsic3d8XN8

    История:

    www.newmoldova.com/?q=node/438
  • 0
    По жизни пользовался (пока была нужда) thinstation (15 МБ) + TFtpd (16 МБ). Файлы конфигурации прописываются индивидуально (+ 170 байт). Получался удаленный рабочий стол за 30-40 сек на достаточно старой машине (800МГц, 256 ОЗУ, -HDD)
  • 0
    Спасибо за статью, как раз интересовался загрузкой по сети.

    Следовал вашим инструкциям и встретил пару небольших проблем:

    mkdir -p /etc/systemd/system/tftpd.service.d && echo -e '[Service]\nExecStart=\nExecStart=/usr/bin/in.tftpd -s /srv/nfs/boot' > /etc/systemd/system/tftpd.service.d/directory.conf

    Во-первых, в итоговом файле будет две строчки ExecStart, на что systemd будет ругаться и не будет запускать tftpd. Исправление файла и многократный вызов systemctl daemon-reload почему-то не помогали. Перезагрузка помогла. Так и должно быть?

    Во-вторых, у вас указан путь /srv/nfs/boot, а нужен /srv/nfs/diskless/boot. Иначе, опять же, tftpd не запускается. Возможно, имеет смысл переписать на echo -e "[Service]\nExecStart=\nExecStart=/usr/bin/in.tftpd -s $root/boot", во избежание опечаток в будущем.

    И совсем мелочь: systemctlt enable tftpd.socket tftpd.service dhcpd4 rpcbind nfs-server — лишняя буква T на конце systemctl.

    Еще раз спасибо за статью.
    • 0
      Спасибо за интерес и внимательность. Действительно должно быть так:
      cat /etc/systemd/system/tftpd.service.d/directory.conf
      [Service]
      ExecStart=
      ExecStart=/usr/bin/in.tftpd -s /srv/nfs/diskless/boot


      В случае нескольких юнитов в одной строке команда:
      systemctl restart tftpd.socket tftp.service
      может сработать неадекватно. Вот такая связка обычно срабатывает без проблем:
      systemctl stop tftpd.socket tftp.service && systemctl start tftpd.socket tftp.service
      В этом случае юниты перезапускаются строго в указанном порядке.
      • 0
        То есть у вас специально два раза ExecStart? А зачем?
        • 0
          Пустая строка «ExecStart=» отменяет действие предыдущей команды из модифицируемого юнита /usr/lib/systemd/system/tftpd.service/.

          Попробуйте убрать строку «ExecStart=» и перезапустите. Сервис не запустится по причине:
          tftpd.service has more than one ExecStart= setting, which is only allowed for Type=oneshot services. Refusing.

          Есть единственный на данный момент тип сервиса — Type=oneshot, в котором можно указывать несколько команд ExecStart=, и все эти команды будут выполняться одна за другой. Сейчас я сделаю пояснение в тексте статьи.

          И я опечатался в предыдущем сообщении в слове tftpd (нужно указывать tftpd, а не tftp). Вот исправленная связка:
          systemctl stop tftpd.socket tftpd.service && systemctl start tftpd.socket tftpd.service

          • 0
            Ах вот оно как! Я-то решил, что первый ExecStart это опечатка. Спасибо за разъяснение!
  • 0
    Не получается как по писаному:
    на запуск сервиса
    systemctl start tftpd.socket tftpd.service
    TFTP выдаёт:

    ● tftpd.service — hpa's original TFTP daemon
    Loaded: loaded (/usr/lib/systemd/system/tftpd.service; disabled; vendor preset: disabled)
    Drop-In: /etc/systemd/system/tftpd.service.d
    └─directory.conf
    Active: failed (Result: exit-code) since Чт 2016-04-21 03:43:34 NOVT; 1min 29s ago
    Process: 7055 ExecStart=/usr/bin/in.tftpd -s /srv/nfs/diskless/boot (code=exited, status=74)

    апр 21 03:43:34 ArchServer systemd[1]: Starting hpa's original TFTP daemon…
    апр 21 03:43:34 ArchServer systemd[1]: tftpd.service: Control process exited, code=exited status=74
    апр 21 03:43:34 ArchServer systemd[1]: Failed to start hpa's original TFTP daemon.
    апр 21 03:43:34 ArchServer systemd[1]: tftpd.service: Unit entered failed state.
    апр 21 03:43:34 ArchServer systemd[1]: tftpd.service: Failed with result 'exit-code'.
    • 0
      journalctl -xe
      — Процесс остановки юнита tftpd.socket был завершен.
      апр 21 03:43:34 ArchServer systemd[1]: Starting hpa's original TFTP daemon…
      — Subject: Начинается запуск юнита tftpd.service
      — Defined-By: systemd
      — Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
      — — Начат процесс запуска юнита tftpd.service.
      апр 21 03:43:34 ArchServer in.tftpd[7055]: recvfrom: Socket operation on non-soc
      апр 21 03:43:34 ArchServer systemd[1]: tftpd.service: Control process exited, co
      апр 21 03:43:34 ArchServer systemd[1]: Failed to start hpa's original TFTP daemo
      — Subject: Ошибка юнита tftpd.service
      — Defined-By: systemd
      — Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
      — — Произошел сбой юнита tftpd.service.
      — — Результат: failed.
      апр 21 03:43:34 ArchServer systemd[1]: tftpd.service: Unit entered failed state.
      апр 21 03:43:34 ArchServer systemd[1]: tftpd.service: Failed with result 'exit-c
      апр 21 03:52:30 ArchServer systemd[1]: Listening on hpa's original TFTP daemon.
      — Subject: Запуск юнита tftpd.socket завершен
      — Defined-By: systemd
      — Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
  • 0
    проблема собственно в этом:
    апр 26 17:25:00 ArchServer in.tftpd[1476]: recvfrom: Socket operation on non-socket

    Как так получается?
    • 0
      Если мне не изменяет память, то ещё в конце прошлого года изменился синтаксис запуска TFTP. Подобные неожиданности периодически случаются в archlinux. В предыдущий раз разработчики сломали NBD, и пришлось добавлять костыль, описанный в статье.

      Создайте файл /etc/conf.d/tftpd
      TFTPD_ARGS="--secure /путь_к_папке"
      


      Файл /etc/systemd/system/multi-user.target.wants/tftpd.service должен выглядеть так:
      [Unit]
      Description=hpa's original TFTP daemon
      After=network.target
      
      [Service]
      Type=forking
      EnvironmentFile=/etc/conf.d/tftpd
      ExecStart=/usr/bin/in.tftpd --listen $TFTPD_ARGS
      
      [Install]
      WantedBy=multi-user.target
      


      Рекомендую проверять работоспособность на каждом этапе. Информация стареет очень быстро.
      • 0
        Добрый день!
        А разве параметр --listen не запускает сервис в режиме standalone server без использования сокета?
        Насколько помню раньше именно отсутствие данного параметра --listen указывало сервису, что сервис должен работать в режиме с использованием сокета. В таком случае если не ошибаюсь он не будет постоянно висеть в памяти на прослушке порта, а будет работать только когда данные будут поступать через сокет.
        Или он теперь постоянно в этом режиме работает, используя tftpd.socket?
        • 0
          К сожалению, я давно переключился на немного иные проекты. Вам придётся самостоятельно разбираться с возникающими проблемами. Советую вам обратить внимание на строку 'Type=forking', возможно, это наведёт вас на какие-то мысли.

          Ещё посмотрите вот эту публикацию LTSP: Терминальный сервер на Linux. Возможно, что использовать готовое решение окажется намного удобнее и проще.

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.