Интересный способ определить, является ли раздел активным (стоит ли флаг boot)

В Linux, с помощью dd.

Делается это вот такой огромной командой:

PARTREC=$(dd if=$DEV bs=1 count=16 status=none skip=$((0x1BE + 16 * ($PART - 1) )) | od -t x1 -A n |awk '{print $1}')

В переменную $DEV записывается устройство (например /dev/sda), а в переменную $PART — номер раздела, например 1 для /dev/sda1, потом проверяем, что накапало в $PARTREC — если там будет 00 — флаг boot для раздела не установлен, раздел неактивен, если 80 — раздел активный, если что-то еще, ну или с разделом что-то странное, или попытались установить флаг boot логическому разделу. Внезапно, gparted может такое сделать, хотя смысла в этом нет — активным разделом может быть только основной, но не логический и не расширенный.

В принципе, способ логичный — информация о флагах хранится в таблице разделов, надо только знать, как вычислить, а dd может выдернуть нужный байт откуда угодно. Далее od преобразует байт в удобочитаемую форму в шестнадцатеричном виде, забираем значение первого байта awk'ой и проверяем.


Тестовый скрипт

1. На GitHub
2. На PasteBin

Источники

1. The MBR (master boot record) and the Partition Tables. Там как раз подробное описание, как оно выковыривается.
2. Нашел здесь

Эмуляция восстановления при загрузке Acronis True Image с помощью syslinux/extlinux

Преамбула

Принесли мне тут в починку компьютер с наглухо залитыми эпоксидкой USB портами (безопасность же) и поставили задачу переустановить винды, в связи с заменой сгоревшего HDD на новый. По счастью сетевой порт был, так что единственным доступным способом доставить туда винды, был PXE. Но, в данном случае, речь пойдет не о PXE.
Зная клиента, который, несмотря на солидность, периодически «придет, и молча уронит все», я подумал, что так дело не пойдет. Надо предусмотреть возможность восстановить если что, ОС прямо с компьютера. Чтоб клиент не бегал вокруг меня, если уронит винду из-за кривого ПО/рук.

Всем хорош образ загрузочного диска Acronis True Image, и копию ОС сделать может, и восстановить может, и Зону Безопасности (скрытый раздел для хранения бэкапов) создать может. Не может лишь одного — установить свой загрузчик, чтобы можно было сделать «Восстановление при загрузке».

В десктопной платной версии такая функция есть, а в Recovery CD буржуи ее вырезали. Но мы не дворяне, справимся.
Внимание! Все нижеследующее работает для компьютеров с BIOS (или в Legacy-режиме) с MBR-дисками.

Необходимые инструменты

— Загрузчик syslinux. Можно взять здесь. Я пользовался версией 4.02, которая мне уже была знакома по настройке PXE-сервера. Из архива нам понадобятся только некоторые файлы, но я уже собрал готовый пакет, ссылка на который будет в конце заметки. Вместо syslinux можно использовать какой-нибудь другой загрузчик, который умеет грузить ISO-образы (например grub2 или grub4dos), но далее все будет про syslinux.

Примечание: Вообще syslinux, это набор загрузчиков на разные случаи жизни. Он включает в себя pxelinux (для загрузки из сети), isolinux (для создания загрузочных ISO) и extlinux, для установки загрузчика на жесткий диск. Но, с 4 версии постановили extlinux и syslinux считать одним и тем же [1], так чтоб никого не путать, далее буду называть все syslinux‘ом

— Какой-нибудь маленький live-дистрибьютив Linux. Я использовал уже довольно пожилой Puppy Slacko 5.5 Rus, немного модифицированный когда-то давно под работу с tcplay
— Собственно сам образ Acronis True Image Recovery CD. Использовал старый, от Acronis True Image 2011, потому что он довольно небольшой (122 Мб против 522 от Acronis True Image 2015, например). Поскольку это софтина проприетарная, пользуйтесь гуглем и торрентами.

Делим диск и ставим Windows

Я все делал на чистом диске, так что мне было просто.
В начале диска создаем основной раздел EXT2 или EXT3, в котором будет установлен загрузчик, лежать образ Acronis True Image, а у меня еще и дистрибьютив Puppy Slacko, чтоб чуть что можно было загрузиться в обход основной ОС. Делаем с помощью любимого менеджера дисков (я пользовался Acronis Disk Director).

Структура разделов должна выглядеть как-то так:

Желательно сделать раздел для нашего будущего загрузчика в начале диска, чтоб потом не было эксцессов. Когда экспериментировал с этим делом первый раз, Acronis, при создании Зоны безопасности, нагло передвинул раздел, и все пошло прахом.
Syslinux, на самом деле, можно ставить и в логические разделы, только это сопряжено с большими телодвижениями (см. в источниках в конце заметки).

Установим Windows на свободное место. Установщик Windows 7 и выше сам создаст необходимые разделы под свой загрузчик (bootmgr и настройки) и основной раздел с ОС. После установки Windows структура диска должна выглядеть так:

Сборка пакета для установки загрузчика

Просьба линуксоидам камнями не кидаться, «пакет», в данном случае, не совсем то, что подразумевается под пакетом в терминах Linux-систем. В данном случае, это набор файлов, который необходим для установки syslinux на целевой машине. Я делал это на «большом» Линуксе, но можно делать это и на том же самом Puppy (и даже в Windows, хотя на практике я не проверял). Ленивые могут пропустить этот шаг, готовый пакет будет в конце заметки.
1. Создаем в удобном месте подкаталог, например slinstall, там будет готовый набор файлов для целевой машины.
2. В другой подкаталог распаковываем архив с syslinux (например, syslinux-4.02.tar.gz), в нашем примере подкаталог будет называться sysl-distr
3. Копируем в каталог slinstall файл extlinux из каталога sysl-distr/extlinux — это установщик загрузчика.
4. Создаем в каталоге slinstall подкаталог mbr и копируем туда файлы sysl-distr/mbr/mbr.bin и distr/mbr/altmbr.bin
5. Создаем в каталоге slinstall подкаталог modules и копируем туда модули загрузчика.

Syslinux, на самом деле, не просто загрузчик, а, можно сказать, целая маленькая операционная система. Функции загрузчика расширяются модулями — файлами специального формата, которые загрузчик может выполнять, примерно как ОС исполняемые файлы. Файлы эти имеют расширение c32 (*.c32). Минимальный набор модулей для нашей задачи — модуль отображения меню menu.c32 и модуль chain.c32 — он передает загрузку другим (не-Linux) операционным системам, загрузчикам, или просто в нужный раздел диска. Но можно скопировать и другие модули, если захочется расширить функционал начальной загрузки. Необходимо найти нужные файлы (через поиск mc в Linux или любым удобным способом) в каталоге sysl-distr и скопировать их в slinstall/modules
В Линукс это можно сделать из командной строки так (находясь в каталоге sysl-distr):

find ./ -name "*.c32"|xargs -I {} cp '{}' /home/user/slinstall/modules

где /home/user/slinstall/modules — полный путь к подкаталогу slinstall/modules

6. В slinstall/modules необходимо также скопировать специальный модуль memdisk, предназначенный для загрузки ISO-образов. Обычно расположен по пути memdisk/memdisk в каталоге с распакованным syslinux (тут sysl-distr).

7. Пакет готов, теперь можно запаковать его в архив, и приступать к установке загрузчика.
В Linux можно выполнить (выйдя из каталога slinstall на уровень выше)

tar -czvf syslinux-install.tar.gz ./slinstall

Копирование необходимых файлов на раздел EXT2/EXT3 целевого компьютера.

Предположим, у нас есть загрузочная флешка с Puppy Linux (или другим Linux на ваш вкус), копируем на нее образ Acronis True Image, выше созданный пакет с загрузчиком, и архив с дистрибутивом самого Puppy (см. ниже, в разделе «Скачать»).

В графическом интерфейсе все можно делать мышью, я приведу ниже консольные команды. В данном примере флешка — sdb1, а созданный ранее раздел — sda1

Внимание! Не ошибитесь в том, как именованы разделов на конкретной машине!

1. Создаем точки монтирования (пропустить шаг, если запущен графический интерфейс Puppy. Просто щелкнуть мышью по нужной иконке диска на desktop’е)

mkdir /mnt/sda1
mkdir /mnt/sdb1

2. Монтируем диски (пропускается из графического интерфейса):

mount -t ext3 /dev/sda1 /mnt/sda1
mount -t vfat /dev/sdb1 /mnt/sdb1

Может быть нужным заменить ext3 на ext2 и/или vfat на ntfs в зависимости от используемых файловых систем.

3. Создаем директорию для образа Acronis True Image Recovery CD на разделе sda1 и копируем образ.

mkdir /mnt/sda1/acronis
cp /mnt/sdb1/loader.iso /mnt/sda1/acronis/

4. Копируем и распаковываем дистрибутив Puppy (если он нужен)

cp /mnt/sdb1/puppy-slacko-rus-5.5-hexmod.tar.gz /mnt/sda1/
cd /mnt/sda1
tar -xvf puppy-slacko-rus-5.5-hexmod.tar.gz
rm puppy-slacko-rus-5.5-hexmod.tar.gz

5. Копируем и распаковываем пакет установки syslinux:

cp /mnt/sdb1/ syslinux-install.tar.gz /mnt/sda1/
cd /mnt/sda1
tar -xvf syslinux-install.tar.gz
rm syslinux-install.tar.gz

Устанавливаем загрузчик syslinux

Внимание! Установка syslinux производится не на устройство, а на заранее смонтированный раздел. Загрузчик нельзя устанавливать в корень диска, необходимо создать для него каталог, например /boot/syslinux. Не перепутайте разделы диска, куда устанавливаете загрузчик! Раздел с загрузчиком должен иметь файловую систему FAT, ext2, ext3, ext4 или Btrfs

1. В любимом менеджере дисков делаем раздел EXT2/EXT3 активным.
2. Загружаемся, если еще не, в live-дистрибьютив Linux.
3. Создаем точку монтирования и монтируем раздел (если еще не сделано)

mkdir /mnt/sda1
mount -t ext3 /dev/sda1 /mnt/sda1

4. Создаем каталог для загрузчика:

mkdir -p /mnt/sda1/boot/syslinux

ключ -p указывает команде mkdir, что нужно создавать путь со всеми подкаталогами.

5. Создаем каталог для модулей и копируем их:

mkdir -p /mnt/sda1/boot/syslinux/modules
cp /mnt/sda1/slinstall/modules/* /mnt/sda1/boot/syslinux/modules

6. Переходим в каталог slinstall и устанавливаем загрузчик:

cd /mnt/sda1/slinstall
./extlinux --install /mnt/sda1/boot/syslinux

Если все сделано верно, последняя команда выдаст сообщение:

/mnt/sda1/boot/syslinux is device /dev/sda1

В каталоге /mnt/sda1/boot/syslinux должен находиться файл ldlinux.sys, кстати, неудаляемый. В [1] написано, как его, если что, удалить.

Настройка MBR

Syslinux, внезапно, сам не умеет прописываться в MBR диска, да и в загрузочный сектор раздела. Так что если перезагрузиться сейчас, то получим при загрузке сообщение Boot error и глухое зависание. MBR, к сожалению, придется править вручную, с помощью команды dd.

Внимание! Команду dd не зря называют Disk Destroyer, будьте с ней очень осторожны! При ошибке легко можно похерить не только MBR, но и таблицу разделов, и данные на диске!

MBR находится в первых 440 байтах на диске.

1. Переходим в каталог slinstall:

cd /mnt/sda1/slinstall

(естественно, точка монтирования должна быть создана, а раздел примонтирован).

1. Создаем копию текущей MBR:

dd if=/dev/sda of=old.mbr bs=440 count=1

В текущем каталоге должен появиться файл old.mbr размером 440 байт. Можно, и даже желательно, указать и какой-нибудь другой путь к файлу old.mbr, сохранив его, например, на флешке:

dd if=/dev/sda of=/mnt/sdb1/old.mbr bs=440 count=1

2. Устанавливаем MBR syslinux:

dd bs=440 count=1 conv=notrunc if=mbr/mbr.bin of=/dev/sda

Примечания:

Краткое пояснение по команде dd:
bs=<число> — сколько байт необходимо прочитать.
count=<число> — число уазывает на то, сколько раз будет прочитано количество байт, указанное в параметре bs=
if=<путь к устройству или файлу> — откуда будут прочитаны данные
of=<путь к устройству или файлу> — куда будут записаны данные

Осталось сделать загрузочное меню.

Загрузочное меню

Вот пример загрузочного меню, главное, правильно установить раздел с загрузчиком винды — в syslinux отсчет разделов ведется с единицы (0 — MBR жесткого диска), отсчет дисков с ноля, и надо помнить, что единица таймера загрузки syslinux равна 0.1 секунде.

ui modules/menu.c32
PROMPT 0

menu title Local boot

LABEL windows
   menu label Microsoft Windows 7
   kernel modules/chain.c32
   append hd0 2
   timeout 1000
 TEXT HELP
    Loading Windows 7
 ENDTEXT

LABEL recovery
    menu label System recovery
    kernel modules/memdisk
    initrd ../../acronis/loader.iso
    append iso raw

LABEL slacko
    menu label Puppy Linux Slacko 5.5
    kernel ../../slacko/vmlinuz
    initrd ../../slacko/initrd.gz

На PasteBin

Осталось загрузиться с жесткого диска, создать зону безопасности Acronis и сделать бэкап первых трех разделов в нее


Вот финальная структура диска.

Источники

1.Syslinux (Русский)
2. Comboot/chain.c32
3. Syslinux wiki

Архивы

puppy-slacko-rus-5.5-hexmod.tar.gz
syslinux-install.tar.gz
syslinux-mini.tar.gz

[ВЫЦВЕЛО] Виктор Багров

По случаю понаезда к нам означенного в заголовке товарища.

У него, однако, вышла книга стихов. Давно вышла, но до редакции дошла только сейчас, посему исправляю досадное упущение и нагло пиарю товарища на сайте.

В.Б. активный УФОшник и член нашего общества «Дельта». Как и все поэты и УФОшники, ебанут наглухо, но в правильную сторону. Старые стихи есть на LJR в блоге [info]hronos@ljr, можете ознакомиться (из ГОРФ через прокси или VPN).

Видео с презентации книги:

https://www.youtube.com/watch?v=4VCnKEF68wE

Саму книжку можно взять на «Озоне», купите, поможете автору.

Включение цифровой клавиатуры (NumLock) при загрузке Slackware (и/или X-Server)

Slackware, почему-то загружается по умолчанию с отключенной цифровой клавиатурой, еще и благополучно плюет на опцию Boot Up Numlock в BIOS, благо все это, как оказалось, легко поправить. Раньше было не так актуально, но завелся на работе ноут с полноценной клавой с цифровым блоком. Так что заметка опять же от склероза.

Включение NumLock при загрузке в «голую» консоль.

Надо помнить, что у нас как минимум 6 терминалов (которые переключаются по CTRL+ALT+F1 — F6), можно активировать цифровую клавиатуру для всех шести, таким вот простым скриптом:

#!/bin/bash

for TTYNUM in 1 2 3 4 5 6; do 
    /usr/bin/setleds -D +num < "/dev/tty$TTYNUM"; 
done

Сохраняем, например в /etc, под именем, скажем, numlockon, и дописываем в /etc/rc.d/rc.local

Код на PasteBin

Можно вообще не делать отдельный файл, а прямо в rc.local записать все в одну строку:

for TTYNUM in 1 2 3 4 5 6; do; /usr/bin/setleds -D +num < "/dev/tty$TTYNUM"; done

Кому почему-то первая версия не подходит, можно попробовать версию с ArchLinux вики, там активируется NumLock на консолях от tty0 до tty9.

Код на PasteBin

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

Включение NumLock при старте X-Server

Скачиваем и собираем утилиту numlockx, она есть в репозиториях sbopkg, например.

Потом останется прописать ее в автозагрузку для конкретного пользователя. Тут расскажу про XFCE, остальные будут в источниках.

1. Заходим в Applications —> Settings —> Session and Startup

2. Переходим на вкладку Application Autostart, нажимаем кнопку Add.


3. Заполняем название, описание, вписываем в соответствующее поле саму команду numlockx:

4. Готово, закрываем все приложения и перезагружаем иксы:

Источники

1. man setleds
2. Activating Numlock on Bootup (Русский)

Изменение имени страницы входа в админ-панель WordPress

Преамбула

Да, эта информация есть много где в сети, но в некоторых версиях почему-то кое что пропущено, так что эта заметка из серии «от склероза».
Известно, что страница входа в админ-панель по умолчанию носит имя wp-login.php (например tolik-punkoff.com/wp-login.php), и в нее ломятся всякие противные боты и школохацкеры, с целью поломать сайт. Далее простой способ, как защитить сайт от этого. Всегда так делаю, вместе с другими мерами безопасности, конечно же. Из которых самый главный — регулярный бэкап.

Плюсы:

+ Дополнительные плагины не нужны.
+ Делается просто

Минусы:

— Для многопользовательского блога не подходит, но если админов немного — вполне (просто надо раздать всем ссылку на новую страницу входа).
— После глобального обновления WordPress будет слетать, и все придется делать снова.

Меняем имя страницы входа в админ-панель

1. Разлогиниваемся на сайте.

2. Скачиваем по FTP с сайта файлы
wp-login.php
wp-includes/general-template.php

3. Делаем резервную копию этих файлов.

4. Копируем wp-login.php под каким-нибудь другим именем (ctulhu.dot.com.php, 47767deedbeaf6587.php, в общем сами придумайте что-нибудь уникальное).

5. Открываем получившийся файл в любимом текстовом редакторе (редакторе Far’а, mcedit’e, Notepad++) запускаем поиск и замену. Ищем wp-login.php, меняем на новое имя странички входа. Сохраняем изменения

6. Повторяем предыдущий пункт для файла general-template.php

7. В файл wp-login.php заменяем содержимое на следующий код:

<?php
		header('Location: http://natribu.org', true, 301);
?>

8. Убираем виджет авторизации с сайта.

9. Закачиваем измененные файлы обратно на FTP, заменяя старые версии.

Ограничение доступа к каталогу wp-admin

К сожалению, если вы введете адрес yoursite.com/wp-admin, то вас, и злоумышленника, перебросит на страницу авторизации. Самое простое решение — перекрыть доступ со всех IP, кроме доверенных, например, создав а каталоге wp-admin файл .htaccess со следующим содержимым:

order deny,allow
allow from 6.6.6.6
deny from all

где вместо 6.6.6.6 IP с которого будете заходить на сайт в админ-панель.

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

Добавление русской раскладки в X-Server на Slackware

1. Копируем файл 90-keyboard-layout.conf из /usr/share/X11/xorg.conf.d/ в /etc/X11/xorg.conf.d/

2. Смотрим варианты переключения клавиатуры:
grep "grp:.*toggle" /usr/share/X11/xkb/rules/base.lst

Выдаст примерно вот такой список:

  grp:toggle           Right Alt
  grp:lalt_toggle      Left Alt
  grp:caps_toggle      Caps Lock
  grp:shift_caps_toggle Shift+Caps Lock
  grp:alt_caps_toggle  Alt+Caps Lock
  grp:shifts_toggle    Both Shift keys together
  grp:alts_toggle      Both Alt keys together
  grp:ctrls_toggle     Both Ctrl keys together
  grp:ctrl_shift_toggle Ctrl+Shift
  grp:lctrl_lshift_toggle Left Ctrl+Left Shift
  grp:rctrl_rshift_toggle Right Ctrl+Right Shift
  grp:ctrl_alt_toggle  Alt+Ctrl
  grp:alt_shift_toggle Alt+Shift
  grp:lalt_lshift_toggle Left Alt+Left Shift
  grp:alt_space_toggle Alt+Space
  grp:menu_toggle      Menu
  grp:lwin_toggle      Left Win
  grp:win_space_toggle Win Key+Space
  grp:rwin_toggle      Right Win
  grp:lshift_toggle    Left Shift
  grp:rshift_toggle    Right Shift
  grp:lctrl_toggle     Left Ctrl
  grp:rctrl_toggle     Right Ctrl
  grp:sclk_toggle      Scroll Lock

Выбираем понравившийся вариант, правим /etc/X11/xorg.conf.d/90-keyboard-layout.conf
Например, для раскладки en/ru с переключением по Ctrl+Shift.

Section "InputClass"
	Identifier "keyboard-all"
	MatchIsKeyboard "on"
	MatchDevicePath "/dev/input/event*"
	Driver "evdev"
	Option "XkbLayout" "us,ru"
	#Option "XkbVariant" ""
	Option "XkbOptions" "grp:ctrl_shift_toggle,terminate:ctrl_alt_bksp"
EndSection

Источники

1. Slackware.ru
2. Всякие дополнительные подробности на wiki.archlinux.org

Локальный хронопрорыв

В российской редакции случайно произошел хронопрорыв в СССР

А вот не надо было совок и альтернативную физику обсуждать.
Собственно, рюмку «Шипра» я даже выпил на спор с Лехой, который имел честь посетить наш славный городок.
«Шипр», тащемта, абсолютно аутентичный, честно спертый с объекта во время ремонта.

Чебурнет и все-все-все.

В ЕС приняли цензурирующий Интернет говнозакон, и вообще, очебурашивание Интернета по всему миру идет полным ходом. ГОРФ, изначально скопировав, простите за каламбур, законы о копирайте у запада, а потом добавив туда коктейль из мнимой безопасности и черносотенных скреп, пока идет второй, или даже третьей (вперде, как минимум, КНДР и КНР). Евросовок пока отстает, посмотрим, что будет.

Но, не понаслышке зная скачки, ваш покорный слуга все-таки полагает, что неопытная, но рьяно начавшая заезд лошадь, все-таки скачки не выигрывает. И тут дело не в лошади (быдлочасти народа), и не в жокее (правительстве), а в неумелом расходе сил. Т.е. в распиле, откате, или даже просто раздолбайстве. Если от первого и второго можно попытаться избавиться, и то не факт, но с третьим с каждым годом будет все лучше и лучше (для правительства, конечно, хуже).

Не буду растекаться мысию по древу, просто расскажу старый случай из практики.
В 2010 году меня позвали в качестве сисадмина в одну государственную организацию, которой необходимо было срочно переходить на «электронный документооборот» с налоговой, Федеральным Казначейством, Пенсионным Фондом и кучей других контор. Заодно в силу вступил закон о персональных данных, и т.д., и т.п.
В результате в один не прекрасный день приехал директор с совещания в министерстве, и сказал, «Родина сказала «Надо!», ищите специалиста».

Буду краток — надо «уже вчера», а все инструкции писаны для москвы, где есть гигабитные каналы интернета, хорошие провайдеры и прочее и прочее…
У меня был непролазный лес, сгнившие столбы телефонных линий, которых пугался ADSL, мобильный интернет, обеспечивающий соединение, когда Марс в противостоянии с Сатурном, и если Венера в Стрельце, а Луна в Козероге.

Так вот, к чему я веду. Правительство, вместо того, чтобы сначала обеспечить и организовать инфраструктуру, все проверить, внедрить оптимизированное стандартное ПО (про ПО, с которым я работал, лучше не буду — даже zadolba.li порвется), просто раздало всем бумажку — надо было вчера.

Ладно, кто старое помянет, тому коннектор из порта. Все-таки сейчас не 2010, а 2019.

Решил я купить на прошедший Новый Год лотерейный билет. Купил заранее, на официально одобренном сайте государственной лотереи, как честный законопослушный гражданин.

В день розыгрыша захожу на сайт, и вижу следующую картину:

Вижу эту же картину еще 3 часа подряд (проверял и засекал).

А ведь это не политический «чебурнет», это живые деньги тех людей, которым государство запретило играть в автоматы (безотносительно того, хорошо это или плохо в принципе). Государство просто решило — если нельзя побороть (а склонность к азартным играм побороть может только сам игрок), то надо возглавить.

Вот и возглавили, как смогли. Я думаю, если бы у сайта ***тритопора, ****88***, казинопукан или других подобных «пиратских» сервисов произошел обвал исключительно из-за наплыва клиентов, которые ринулись проверять свой выигрыш, то сисадмин, как минимум, был бы распят владельцами сервиса, и даже без всяких трусиков. А вообще, такого бы не случилось.

Так что надежда на завтра остается. Распиздяйство и некомпетентность вполне могут победить высокодуховную скрепность.

Верю и надеюсь, что самой популярной в мире страной, станет республика, где в конституции будет прописано, что государство не имеет права вмешиваться в деятельность Интернета, кроме как ради предотвращения угроз для самого Интернета — борьба со спамом, вирусами, ботнетами и физическим повреждением каналов, а вся контент-политика определяется только владельцами сайтов. Причем хостер, т.е. фактический владелец «земли», может тоже прописать в условиях использования, что контент-политика определяется клиентом самостоятельно, а хостеру не до этого. Получится этакий цифровой Дикий Запад, и это будет хорошо.

Скрипт для поиска загрузчика Windows из Linux-окружения.

Преамбула

Найти загрузчик Windows на разделе жесткого диска, дело не очень сложное:

1. Надо проверить файловую систему раздела, она должна быть FAT32 или NTFS
2. Проверить наличие файла ntldr (Windows XP и ранее) или bootmgr (Windows Vista и позднее) в корне раздела. Windows XP и старше, при установке по умолчанию, записывают файл ntldr в корень системного раздела, а более новые — создают отдельный загрузочный раздел, в корне которого лежит bootmgr.

Для чего? Например, для создания своего скрипта автоматической настройки загрузчика Grub или Syslinux

Поиск разделов NTFS и FAT32

Я недавно писал о том, как узнать файловую систему раздела (диска) в Linux Копия. В данном случае действовать будем примерно также.

Обработать вывод команды blkid (вывод данных о блочных устройствах) можно в цикле for:

echo "Find Windows loaders..."

IFS=$'\n'

for DEVDATA in $(blkid); do
...
done

Перед циклом необходимо установить значение переменной IFS, как \n (перенос строки)
IFS — переменная, задающая разделители полей при работе со строками в shell, по умолчанию разделители это табуляция, перенос строки и пробел, если не установить ее значение, как «только перенос строки», то строка с описанием каждого раздела (например, /dev/sda1: UUID="68DF-FF87" TYPE="vfat" PARTUUID="00003214-01") распадется на части, что поломает алгоритм.

В цикле for:

1. Вытаскиваем в переменную VOL нужные данные — путь к устройству и файловую систему:

VOL=`echo "$DEVDATA" |sed -n 's/\(.*:\).* TYPE=\"\([^\"]*\)\".*/\1\2/p'`

Для вышеуказанного /dev/sda1 получится строка /dev/sda1:vfat

2. Получаем путь к устройству и тип файловой системы отдельно в переменные, соответственно, VOLNAME и VOLFS.

VOLNAME=`echo "$VOL"|awk -F ":" '{print $1}'`
VOLFS=`echo "$VOL"|awk -F ":" '{print $2}'`

Параметр -F ":" устанавливает двоеточие в качестве разделителя полей awk.

3. Далее, проверяем, не пуста ли строка в переменной VOLFS, и проверяем ее значение. Если VOLFS равна ntfs или vfat, то запускаем функцию find_loader(), проверяющую наличие загрузчика в корне соответствующего раздела. Если файловая система раздела другая — выводится сообщение, что это не Windows-раздел.

if [ -n "$VOLFS" ]; then
	if [[ "$VOLFS" == "ntfs" || "$VOLFS" == "vfat" ]];then
		find_loader $VOLNAME  $VOLFS
	else
		echo "$VOLNAME not windows volume"
	fi
fi

Можно было бы еще исключать разделы FAT16, но решил не загромождать скрипт лишней проверкой.

Поиск загрузчика Windows

В функцию find_loader() передаются два параметра: путь к устройству (разделу) и его файловая система.

1. Заведем переменную-флаг, указывающую, был ли раздел временно смонтирован
TMPMOUNT=0

2. Получаем выхлоп команды mount. grep‘ом фильтруем вывод по соответствующему разделу, с помощью awk вытаскиваем точку монтирования.

MOUNTPOINT=`mount|grep -w "$1"|awk '{print $3}'`

3. Если переменная MOUNTPOINT пустая, раздел не смонтирован. Создаем временную точку монтирования, пытаемся смонитровать раздел, если получилось — устанавливаем TMPMOUNT=1, в переменную MOUNTPOINT записываем временную точку монтирования и приступаем к поиску загрузчика, если не получилось — выходим из функции:

if [ -z "$MOUNTPOINT" ]; then
	mkdir -p "/tmp/tmpmount"
	mount -t "$2" "$1" "/tmp/tmpmount"
	if [ $? -ne 0 ]; then
		echo "$1 not mounted"
		return
	fi
	MOUNTPOINT="/tmp/tmpmount"
	TMPMOUNT=1
fi

Примечание: ключ -p команды mkdir позволяет создать путь вместе со всеми подкаталогами, а если путь уже создан, то команда mkdir не выдаст ошибки, что путь уже существует.

Надо обратить внимание на то, что Windows нечувствительна к регистру имен файлов, так что загрузчик может быть и bootmgr и BOOTMGR, и даже BoOtMgR (аналогично и ntldr). Поэтому придется воспользоваться командой find.

find <path> -maxdepth 1 -iname <filename>

где:
<path> — путь к каталогу, с которого начинать поиск
-maxdepth — глубина поиска в подкаталогах (начиная с указанного в <path>, 1 — только каталог <path> без подкаталогов).
-iname — игнорировать регистр имени файла
<filename> — имя файла (или маска), который будем искать.

В данном случае надо обязательно установить -maxdepth 1, иначе будут большие тормоза, а при отмонтировании возможны глюки.

4. Ищем загрузчик Vista и выше и сохраняем выхлоп в переменную FOUND:

FOUND=`find "$MOUNTPOINT" -maxdepth 1 -iname "bootmgr"`

5. Если нашли (переменная FOUND не пустая), выводим соответствующее сообщение, если нет — ищем загрузчик Windows XP, и выводим сообщение в зависимости от того, нашли или нет:

if [ -n "$FOUND" ];then
	echo "$1: found bootmgr (Windows Vista and newer)"
else
	#ntldr - Win XP and older
	FOUND=`find "$MOUNTPOINT" -maxdepth 1 -iname "ntldr"`
	if [ -n "$FOUND" ];then
		echo "$1: found ntldr (Windows XP and older)"
	else
		echo "$1: Windows loader not found"
	fi
fi

6. Проверяем флаг TMPMOUNT, если он был установлен в 1, отмонтируем временно смонтированный раздел:

if [ $TMPMOUNT -eq 1 ]; then 
	sleep 1
	umount "/tmp/tmpmount"
fi

Результат работы скрипта

Запуск на тестовой машине с разделами FAT32/NTFS, но без установленной Windows:

Запуск на машине с установленной Windows 7:

Запуск на машине с установленной Windows XP

Скрипт целиком

На GitHub
На PasteBin

Источники

1. Определение файловой системы раздела диска в Linux Копия
2. Команда find в Linux Копия

Определение файловой системы раздела диска в Linux.

Преамбула

Понадобилось определять файловую систему еще не смонтированного раздела в Linux, я написал скрипт, который мне самому казался громоздким и неудобным, так и оказалось. Но добрый аноним подсказал, в какую сторону копать, и действительно, нашлось хорошее универсальное решение.

Для экспериментов создал диск с разделами различных файловых систем:

Утилита lsblk

Показывает блочные устройства (диски, разделы, контейнеры, прикрученные к loop-устройствам, разделы, добавленные kpartx, исключая RAM-диски) по умолчанию в виде симпатичного дерева. Ключ -f заставляет утилиту вывести информацию о файловой системе на конкретном устройстве.

lsblk -f

Почти то, что нужно, но, к сожалению, есть эта утилита не везде, так что мне она не подошла.

Команда blkid

При запуске без параметров выводит кучу информации о блочных устройствах (опять же диски, разделы, контейнеры, прикрученные к loop-устройствам, разделы, добавленные kpartx) в виде строк, по одной на устройство, содержащих пары КЛЮЧ="ЗНАЧЕНИЕ":

Можно обратить внимание на ключ -o — он меняет формат вывода на экран, например, blkid -o list выводит информацию в виде таблицы.

Но, к сожалению, менять формат вывода умеют не все версии этой утилиты. Например, «версия», «встроенная» в BusyBox не умеет.

Да! Она есть даже в BusyBox! А значит, это, наверное, самое универсальное решение! А с форматированием вывода как-нибудь разберемся.

Запуск команды, как blkid <устройство>, например, blkid /dev/sda1, позволяет вывести информацию о конкретном устройстве.

Разные мелочи

— И у раздела FAT16, и у раздела FAT32 параметр TYPE будет равен vfat, чтобы их отличить друг от друга, надо смотреть в параметр SEC_TYPE, у раздела FAT32 его не будет вообще, а у раздела FAT16 SEC_TYPE="dos"

— Если вытащить значение поля TYPE в скрипте, его автоматически можно подставить в команду mount, во всяком случае для FAT16/32, NTFS, EXT2(3, 4) и BTRFS

Скрипт, выводящий устройство и его файловую систему.

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

Скрипт целиком:

#!/bin/bash

if [ -z "$1" ]; then
    blkid |sed -n 's/\(.*:\).* TYPE=\"\([^\"]*\)\".*/\1\2/p'
else
    RES=`blkid "$1"`
    RC=$?
    if [ $RC -ne 0 ];then
	echo "$1:Not found or not supported (code $RC)"
    else
	RES=`echo "$RES"|sed -n 's/\(.*:\).* TYPE=\"\([^\"]*\)\".*/\1\2/p'`
	if [ -n "$RES" ];then
	    echo "$RES"
	else
	    echo "$1: Not exist TYPE"
	fi
    fi
fi

Можете сравнить с тем монстром, который я набыдлокодил изначально. Оставлю, чтоб иногда самому ужасаться. 🙂

Скрипт (новый) на GitHub
Скрипт (новый) на PasteBin

Результат работы в нормальном окружении:

И в урезанном, с BusyBox’овой «версией» blkid

Изменение внешнего вида ссылки cut’а в WordPress

И внешнего вида cut’а нашего плагина LJ-cut style plugin for WordPress

Внешний вид ссылки на подкат, и в том и в другом случае управляется CSS-классом a.more-link

Если в CSS-файле вашей темы данный класс не прописан, то ссылка на подкат может выглядеть бледно:

Если так, то заходим в консоль WordPress, в боковом меню выбираем Внешний вид —> Редактор, в редакторе файл style.css, и вставляем на свободное место вне других конструкций CSS, CSS-код стиля more-link:

/*a.more-link*/
a.more-link{
	/*тут параметры стиля*/
}

Например:

/*a.more-link*/
a.more-link{
	font-weight: bold;
	border-bottom:double;
	text-decoration:none;
}

Понятно, что если в CSS темы стиль more-link уже прописан, то меняем его по своему усмотрению.

Теперь ссылка на подкат стала выглядеть симпатичней:

Статья про наш плагин, позволяющий делать в блоге WordPress кат, как в ЖЖ Копия

Макрос замены форматированного текста на HTML, апдейт

Леша его немного подновил, благодарю.

Заметка про макрос для вставки HTML-тегов. Столетней давности приблуда, еще Дима на ЛЖР делал, а до сих пор пользуемся.

Сделал ему репозиторий на GitHub, ибо Леша в свой GitHub почему-то не может меня добавить.

Определение номера колонки таблицы по содержимому (заголовку), для вывода ее awk

Преамбула

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

Задача — вывести колонку с номерами карт (CardID). В простейшем случае, читаем файл с помощью cat, вывод передаем awk и выводим на экран колонку 3.

cat salary1.txt|awk '{print $3}'

Результат:
CardID
6666-6666-6666-0001
6666-6666-6666-0002
6666-6666-6666-0003
6666-6666-6666-0004
6666-6666-6666-0005
6666-6666-6666-0006
6666-6666-6666-0007
6666-6666-6666-0008
6666-6666-6666-0009
6666-6666-6666-0010
6666-6666-6666-0011
6666-6666-6666-0012
6666-6666-6666-0013

Сложнее будет, если место колонки в таблице поменяется, например, в таблицу добавили информацию о банках и воинских званиях сотрудников:

Понятно, что можно номер колонки поменять, или задавать в параметре скрипта, но лучше найти колонку по заголовку. Недавно как раз попалась вполне производственная задача, где программа, в зависимости от ОС, выводила то одну, то другую табличку.

Нашел вопрос по этому поводу на toster.ru, заданный примерно год назад, но без ответов, что удивительно. А ведь там такие акулы и киты программирования с Хабра плавают…

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

Решение

1. Вытаскиваем строчку с заголовками grep‘ом:

cat salary2.txt|grep -w "CardID"

параметр -w, указывает grep‘у вытащить только строки, содержащие слово целиком.

Вывод:
Family Name MilRank BankID CardID Sum

2. Заменяем символы табуляции (\t) на символы перевода строк (\n):

cat salary2.txt|grep -w "CardID"|sed 's/\t/\n/g'

Вывод:
Family
Name
MilRank
BankID
CardID
Sum

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

3. Нумеруем строки с помощью утилиты nl

nl

Вывод:

     1  Family
     2  Name
     3  MilRank
     4  BankID
     5  CardID
     6  Sum

4. grep‘ом вытаскиваем строку с номером нужной колонки:

grep -w "CardID"

Вывод:

     5  CardID

5. Получаем номер колонки с помощью awk:

awk '{print $1}'

Вывод:
5
Пункты 3 и 4 можно оптимизировать, заставив grep нумеровать строки с помощью ключа -n:

grep -w -n "CardID"

Вывод:
5:CardID

Тогда для окончательного определения номера, нужно будет задать awk разделитель двоеточие:

awk -F":" '{print $1}'

Вывод:
5

6. Помещаем результат работы всей команды целиком в переменную:

COLNUM=`cat salary2.txt|grep -w "CardID"|sed 's/\t/\n/g'|nl|grep -w "CardID"|awk '{print $1}'`

или

COLNUM=`cat salary2.txt|grep -w "CardID"|sed 's/\t/\n/g'|grep -w -n "CardID"|awk -F":" '{print $1}'`

7. Теперь в awk нужно передать значение переменной из bash скрипта:

Делается это с помощью ключа -v имя=значение
имя — имя переменной, которое будет использовано внутри скрипта awk
значение — значение переменной

cat salary2.txt|awk -v cnum="${COLNUM}" '{print $cnum}'

Вывод:
CardID
6666-6666-6666-0001
6666-6666-6666-0002
6666-6666-6666-0003
6666-6666-6666-0004
6666-6666-6666-0005
6666-6666-6666-0006
6666-6666-6666-0007
6666-6666-6666-0008
6666-6666-6666-0009
6666-6666-6666-0010
6666-6666-6666-0011
6666-6666-6666-0012
6666-6666-6666-0013

Чтобы не выводить сам заголовок, можно добавить sed '1d':

cat salary2.txt|sed '1d'|awk -v cnum="${COLNUM}" '{print $cnum}'

Немного усложним задачу

Предположим, что в файле две таблицы:

Тогда в переменной $COLNUM после выполнения первой команды, окажется значение
5 11, что на самом деле не есть хорошо. Думаю, понятно, из-за чего этот эффект происходит. Нужно добавить команду head -n1, чтобы оставить только одну строчку после первого grep "CardID".

COLNUM=`cat salary3.txt|grep "CardID"|head -n1|sed 's/\t/\n/g'|grep -w -n "CardID"|awk -F":" '{print $1}'`

В следующей команде так же желательно установить awk разделитель «только символ табуляции», чтоб не отреагировал на пятое слово не в таблице (по умолчанию у awk разделитель полей — табуляция и пробел).

cat salary3.txt|awk -v cnum="${COLNUM}" -F "\t" '{print $cnum}'

Ну и можно удалить sed‘ом пустые строки и строки, содержащие заголовок CardID:

cat salary3.txt|awk -v cnum="${COLNUM}" -F "\t" '{print $cnum}'|sed '/^$/d'|sed '/CardID/d'

Скрипты целиком

На GitHub
Скачать одним архивом с Mega.nz

UPD:
Нашел обсуждение, наведшее на идею

Проверка состояния сетевого устройства (например, eth0) в Linux

Преамбула

Бывает необходимо проверить состояние (статус) того или иного сетевого устройства, например, сетевой карты. Вообще вариантов может быть три:
1. Устройство работает (up)
2. Устройство есть, но не работает в данный момент (down)
3. Устройства нет вообще.

Описание принципа действия

Чтобы определить состояние сетевого устройства, нужно проанализировать вывод команды ifconfig. Если устройство вообще есть, то оно будет в выводе ifconfig -a (ключ -a — все устройства). Если устройство есть, но в данный момент не работает, в выводе ifconfig -a оно будет, в выводе ifconfig — нет.

Например, устройство veth1 в данный момент не работает, вывод ifconfig:

chaosadm@chaos:~# ifconfig
lo: flags=73  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10
        loop  txqueuelen 1  (Local Loopback)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

Вывод ifconfig -a для сравнения:

chaosadm@chaos:~# ifconfig -a
lo: flags=73  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10
        loop  txqueuelen 1  (Local Loopback)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

veth1: flags=4098  mtu 1500
        inet 10.10.0.119  netmask 255.255.0.0  broadcast 10.10.0.255
        ether 62:4e:2c:ad:06:fa  txqueuelen 1000  (Ethernet)
        RX packets 1034  bytes 93233 (91.0 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 136  bytes 12047 (11.7 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0


Значит достаточно отфильтровать вывод ifconfig и ifconfig -a grep‘ом по имени конкретного сетевого устройства, и заставить grep посчитать количество строк (ключ -c):

ifconfig -a | grep eth0 -c

eth0 — имя устройства.

Если количество строк будет 0 — устройства совсем нет.

ifconfig | grep $DEV -c

Если количество строк будет больше 0 — устройство работает (up), если предыдущая команда выдала 1, а эта команда нет, то устройство есть, но не работает (down). Если используются псевдонимы, то надо использовать полные имена (например, eth0:1).

Скрипт

Все это дело можно автоматизировать скриптом.
Продумаем коды возврата: 0 — сетевое устройство работает (up), 1 — устройство не работает (down), 2 — устройство не найдено (none), 3 — неправильные параметры скрипта или запрос справки.
Добавим в скрипт дополнительный параметр -s — если он указан, скрипт не будет выводить сообщений на консоль, а только сигнализировать о статусе сетевого устройства кодом возврата (для использования в других скриптах).

1. Проверяем правильность параметров, выводим помощь:

#!/bin/bash

#check network device status
#exit codes 0 - device up 1 - device down 2 - none device 
#3 - help or wrong parameters

SLNT=0

print_help()
{
    echo "Use "`basename $0`"  [-s]"
    echo " - network device name, e.g. eth0"
    echo "-s - silent mode, no console output"
}

#parameters check and set silent mode
if [ $# -eq 0 ]; then
    echo "Wrong parameters!"
    echo
    print_help
    exit 3
else
    if [ $# -eq 2 ]; then
	if [[ "$2" == "-s" ]]; then
	    SLNT=1
	else
	    echo "Wrong parameters!"
	    echo
	    print_help
	    exit 3
	fi
    fi
fi

#print help
if [[ "$1" == "--help" || "$1" == "-h" ]]; then
    print_help
    exit 3
fi

2. Проверяем наличие устройства вообще:

DEV=$1

# check device exist
DOWN=`ifconfig -a | grep $DEV -c`
if [ $DOWN -eq 0 ]; then
    if [ $SLNT -eq 0 ];then
	echo "Device $DEV: NONE"
    fi
    exit 2
fi

3. Проверяем, работает оно или нет:

#check up/down status
UP=`ifconfig | grep $DEV -c`
if [ $UP -eq 0 ]; then #device down
    if [ $SLNT -eq 0 ];then
	echo "Device $DEV: DOWN"
    fi
    exit 1
else
    if [ $SLNT -eq 0 ];then
	echo "Device $DEV: UP"
    fi
    exit 0
fi

Скрипт целиком

На PasteBin
На GitHub
Пример использования в другом скрипте, который организует Network Namespace’ы

PXE-сервер, сервер для загрузки различных ОС через сеть.

Преамбула

Я тут много писал о том, как запускать различные дистрибутивы по сети, однако, не написал, как, собственно, настроить PXE-сервер. Исправляю досадное упущение. Сервер поднимался на Slackware 14.2, на других линуксах должно быть примерно так же, за исключением того, что некоторый софт придется поставить. В Slackware все, кроме TFTP, было уже «из коробки», оставалось только настроить.

Структура каталогов

PXE-сервер занимает со всеми дистрибутивами довольно много места, у меня был довольно большой раздел /home, вот в нем я и создал подкаталог pxe, в котором создал два подкаталога scripts, для хранения скриптов, дополнительных утилит и бэкапов конфигов, и tftp — будущий корень TFTP-сервера, где завел отдельные подкаталоги для дистрибутивов (distrib) модулей сетевого загрузчика (modules) и загрузочного меню (pxelinux.cfg). В подкаталоге distrib для каждого дистрибутива по возможности создавался отдельный подкаталог. Пример дерева каталогов на PasteBin

TFTP

Ставим TFTP-сервер, я поставил такой же, как в статье, на которой основывался, настраивая сервер [1], atftp, а именно atftp-0.7.1. Поставил через sbopkg. На всякий случай готовый пакет
Поставили, теперь создадим файл /etc/tftpd.rules и запишем в него одну строку:

rg \\ /

Небольшое пояснение: Сетевой загрузчик, о котором будет сказано далее, обращается к TFTP-серверу на удаленной машине, чтобы подгрузить основные файлы — ядра Linux-дистрибутивов, собственные модули, файлы инициализационных RAM-дисков (initrd[.gz]), файлы образов ISO, дискет или жестких дисков. Файл /etc/tftpd.rules и правило rg \\ / нужно, чтобы TFTP-сервер распознал файлы, запрошенные Windows-загрузчиками (т.к. в Windows в качестве разделителя пути используется \, а в Linux /).

Команда запуска TFTP-сервера:

in.tftpd -s /home/pxe/tftp --secure -l -v -r blksize -m /etc/tftpd.rules --blocksize 1456

Без параметра -r blksize у меня TFTP глючил (о чем есть примечание в [1]), --blocksize 1456 несколько ускорил загрузку.
Параметр -s путь устанавливает корневой каталог TFTP-сервера (там будут лежать сетевой загрузчик, дополнительные модули и сами дистрибутивы, поэтому потребуется достаточно места).
-v — заставляет сервер писать логи.
Остальные взял из [1]

Просмотр логов:

TFTP пишет логи в /var/log/messages и некоторые сообщения в /var/log/syslog.
Соответственно команды:
grep tftp /var/log/messages
и
grep tftp /var/log/syslog

Команды остановки сервера:

pkill in.tftpd
sleep 5

Samba

Сам сервер был доступен «из коробки»
Для виндовых дистрибутивов надо поднять Samba. Производим основные настройки в файле /etc/samba/smb.conf

[global]
        workgroup = WORKGROUP
        netbios name = PXE
        server string = Local PXE
        interfaces = 10.10.0.120
        map to guest = bad user
        security = USER
        unix extensions = no
        wide links = yes
        follow symlinks = yes
        log file = /var/log/samba/log.%m
        max log size = 50
        dns proxy = No
        load printers = no
        show add printer wizard = no
        printcap name = /dev/null
        disable spoolss = Yes
        
[printers]
        comment = All Printers
        path = /var/spool/samba
        printable = Yes
        browseable = No

workgroup — рабочая группа (поменяйте на свою)
netbios name — имя компьютера
server string — описание (видно в «Сетевом окружении» из Windows)
interfaces — сетевой интерфейс, который будет прослушивать Samba-сервер. Можно выставить имена сетевых устройств (например, eth0) или задать IP
Делаем доступ к каталогам, открытым в Samba анонимным (без логина и пароля):
map to guest = bad user
security = USER

Следующие 3 строки нужны, чтоб Samba стал поддерживать символические ссылки. У меня, например, дистрибутивы Windows 7 и 10 фактически лежат в каталоге FTP-сервера, а в каталоге дистрибутивов созданы символически ссылки, расшаренные в Samba:
unix extensions = no
wide links = yes
follow symlinks = yes

log file — куда писать лог
max log size — и его максимальный размер

По умолчанию отключаем DNS-proxy и доступ к принтерам:
dns proxy = No
load printers = no
show add printer wizard = no
printcap name = /dev/null
disable spoolss = Yes

Секцию [printers] оставляем по умолчанию (все равно все настройки принтеров вырублены в [global], да и принтеров у меня на этом сервере не было).

Для запуска Samba в Slackware достаточно дать права на исполнение файлу /etc/rc.d/rc.samba и дать команду на запуск:
chmod 744 /etc/rc.d/rc.samba
/etc/rc.d/rc.samba start

Остановка:
/etc/rc.d/rc.samba stop
Если не надо, чтоб сервер Samba стартовал при загрузке ОС, отбираем права на исполнение:
chmod 644 /etc/rc.d/rc.samba

Шары расписаны отдельно для конкретных дистрибутивов в соответствующих заметках, полный пример конфига на PasteBin

NFS

NFS нужен для запуска на удаленной машине некоторых дистрибутивов Linux. Смотрите подробности в соответствующих разделах, посвященных данным дистрибутивам.

В Slackware он так же шел «из коробки», а в конфиге нужно было прописать только конкретные каталоги, открытые для доступа по NFS.

Для запуска NFS нужно поставить права на исполнение следующим файлам:

/etc/rc.d/rc.nfsd
/etc/rc.d/rc.rpc

chmod 744 /etc/rc.d/rc.nfsd
chmod 744 /etc/rc.d/rc.rpc

и запустить NFS-сервер:
/etc/rc.d/rc.nfsd start

Остановка NFS-сервера:
/etc/rc.d/rc.nfsd stop

Если не хотите, чтоб NFS автоматически поднимался при загрузке ОС, отберите права на исполнение:
chmod 644 /etc/rc.d/rc.nfsd
chmod 644 /etc/rc.d/rc.rpc

Полный пример конфига NFS (изменения вносятся в файл /etc/exports)

DHCP

Загрузка по сети устроена так, что BIOS (или EFI) целевой машины передает управление специальной микропрограмме-загрузчику, встроенному в микросхему сетевой карты. Тот пытается получить IP по DHCP, а потом подгрузить с машины, выдавшей IP, основной сетевой загрузчик. В некоторых случаях, если в сети уже есть другой DHCP это может вызвать глюки при загрузке (подробнее см. [1], там описаны конфигурации для сервера, если в сети, например, присутствует маршрутизатор CISCO, раздающий IP по DHCP).
Итак, DHCP надо настроить.
У меня с установкой соответствующего софта опять же, проблем не было, DHCP-сервер шел вместе с ОС, оставалось только настроить.
Копируем старый конфиг куда-нибудь, у меня DHCP до этого был не настроен, потому конфиг был пустой

Составляем конфиг для PXE

Для корректной работы сервера, он должен быть сохранен под именем /etc/dhcpd.conf.

Если не нужно, чтобы DHCP-сервер стартовал постоянно, а, например, только на время работы PXE, то делаем так:
Старт DHCP-сервера:

echo "Copy DHCP daemon PXE config..."
#pxe config must be in current dir.
CURDIR=`pwd`
cp "$CURDIR/dhcpd.conf" /etc/dhcpd.conf
echo "Starting DHCP daemon..."
dhcpd
sleep 5

Остановка DHCP-сервера:

echo "Stopping DHCP daemon..."
pkill dhcpd
sleep 5

echo "Restore DHCP daemon original config file..."
#original config must be in current dir.
CURDIR=`pwd`
cp "$CURDIR/dhcpd.conf.orig" /etc/dhcpd.conf

Полезные скрипты

Объединим все команды для запуска PXE-сервера в один скрипт start-pxe:

#!/bin/bash

echo "Starting TFTP server..."
in.tftpd -s /home/pxe/tftp --secure -l -v -r blksize -m /etc/tftpd.rules --blocksize 1456
sleep 5

echo "Copy DHCP daemon PXE config..."
#pxe config must be in current dir.
CURDIR=`pwd`
cp "$CURDIR/dhcpd.conf" /etc/dhcpd.conf
echo "Starting DHCP daemon..."
dhcpd
sleep 5

#winxp samba
echo "Starting samba server"
chmod 744 /etc/rc.d/rc.samba
/etc/rc.d/rc.samba start
sleep 5

#NFS for live linux
echo "Starting NFS..."
chmod 744 /etc/rc.d/rc.nfsd
chmod 744 /etc/rc.d/rc.rpc
/etc/rc.d/rc.nfsd start
sleep 5

echo "Complete!"

И для остановки (stop-pxe):

#!/bin/bash

echo "Stopping TFTP server..."
pkill in.tftpd
sleep 5

echo "Stopping DHCP daemon..."
pkill dhcpd
sleep 5

echo "Restore DHCP daemon original config file..."
#original config must be in current dir.
CURDIR=`pwd`
cp "$CURDIR/dhcpd.conf.orig" /etc/dhcpd.conf

echo "Stopping samba server"
/etc/rc.d/rc.samba stop
chmod 644 /etc/rc.d/rc.samba
sleep 5

#stop NFS
echo "Stopping NFS..."
ip netns exec provns /etc/rc.d/rc.nfsd stop
chmod 644 /etc/rc.d/rc.nfsd
chmod 644 /etc/rc.d/rc.rpc
sleep 5

echo "Complete!"

start-pxe и stop-pxe на PasteBin.

Сетевой загрузчик SYSLINUX

На самом деле, загрузчик SYSLINUX — это целый комплекс загрузчиков, на все случаи жизни, здесь есть и сетевой — PXELINUX, и загрузчик для ISO-образов ISOLINUX и просто загрузчик ОС с жесткого диска. Пока нам потребуется только сетевой. SYSLINUX представляет собой операционную систему в миниатюре, загрузчик с помощью специальных команд, прописываемых в загрузочном меню, может выполнять специальные функции, сохраняемые в исполняемых файлах особого формата — модулях загрузчика. Обычно они имеют расширение *.c32, и плюс некоторые специальные файлы, например модуль memdisk, загружающий в память ISO-, Floppy- или HDD-образы.

Получение загрузчика: Проще всего его получить с официального сайта, скачав специальным скриптом. Скрипт разберет полученный архив на части, отдельно найдет в скачанном архиве модули *.32, memdisk и сетевой загрузчик pxelinux.0.

#!/bin/bash

SYSLINUXNAME="syslinux-4.02"
SYSLINUXADDR="https://www.kernel.org/pub/linux/utils/boot/syslinux/4.xx/$SYSLINUXNAME.tar.gz" #на Хабре использовали эту, пока оставим
WORKDIR="/tmp"
SERVERDIR="/home/pxe/tftp"

cd $WORKDIR
wget $SYSLINUXADDR
tar -xf "$SYSLINUXNAME.tar.gz"
cd "$SYSLINUXNAME/"
find ./ -name "memdisk" -type f|xargs -I {} cp '{}' $SERVERDIR
find ./ -name "pxelinux.0"|xargs -I {} cp '{}' $SERVERDIR
find ./ -name "*.c32"|xargs -I {} cp '{}' $SERVERDIR

Скрипт на PasteBin

В оригинальной статье [1], была использована версия 4.02, если подумаете использовать какую-то другую, достаточно поменять данные в строке SYSLINUXNAME и/или SYSLINUXADDR

Далее перенесем все файлы *.c32 и memdisk в подкаталог modules (чтоб не мозолили глаза), а сетевой загрузчик pxelinux.0 оставим в корневом каталоге TFTP-сервера.

Тестовое меню

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

Меню по умолчанию описывается в файле default, находящемся в подкаталоге pxelinux.cfg PXE-сервера, там же находятся и дополнительные меню, вызываемые из основного.

Пример тестового меню на PasteBin

Сначала мы подгружаем специальный модуль пользовательского интерфейса modules/menu.c32, который отвечает за загрузку текстового интерфейса меню (подходит для любых компьютеров, даже самых слабых)
ui modules/menu.c32

PROMPT 0 — отключение специального приглашения командной строки.

menu title ChaosServer PXE boot menu — заголовок меню.

Далее идут описания конкретных пунктов меню:

LABEL bootlocal
   menu label Boot from first HDD
   kernel modules/chain.c32
   append hd0 0
   timeout 11120

LABEL reboot
    menu label Reboot
    kernel modules/reboot.c32

параметр timeout включает отсчет времени до загрузки определенного пункта меню 1 единица после параметра timeout составляет 0.1 с

Описание некоторых модулей SYSLINUX

chain.c32 — переключает на следующий загрузчик (grldr, ntldr или просто на загрузчик, установленный на разделе HDD)
reboot.c32 — перезагрузка компьютера
menu.c32 — при использовании в меню, может загружать дополнительные меню (подменю), или производить переход назад/между меню. Пример использования:
Загрузка меню с утилитами Acronis:

LABEL acronis
    menu label Acronis utilities
    kernel modules/menu.c32
    append pxelinux.cfg/acr

Возврат в основное меню:

LABEL back
    menu label Back to main menu
    kernel modules/menu.c32
    append pxelinux.cfg/default

memdisk — специальный модуль, выполненный как псевоядро Линукс, может загружать образы ISO, HDD или дискет в оперативную память и передавать им дальнейшую загрузку. Пример использования:

LABEL acronis2011
    menu label Acronis True Image 2011
    kernel modules/memdisk
    initrd distrib/acr/acronis2011/loader.iso
    append iso raw

Основное меню

На PasteBin

Дополнительные утилиты и скрипты

createiso — скрипт для создания ISO-образов
mknetboot.sh (скрипт для Puppy Slacko и подготовки к PXE-запуску этого дистрибутива)
syslinux-install.bash — скрипт для скачивания SYSLINUX

Осталось наполнить наш PXE-сервер

конкретными дистрибутивами Windows, Linux и другими (копия)

Источники

1. Загрузочный сервер — как загрузочная флешка, только сервер и по сети Копия в PDF Копия в DOC

Скачать

atftp 0.7.1 (готовый пакет для Skackware)
Конфиги
Меню
Скрипты
Дополнительные утилиты
Модули PXELINUX, загрузчик, структура каталогов

Вывод на экран и сохранение в файл дерева каталогов в Linux

Вывести на экран дерево каталогов в Linux можно следующей командой:

tree -d -R

-d — выводит только каталоги
-R — выводить рекурсивно (т.е. до последнего вложенного каталога)

Если вместо -d использовать параметр -a, команда выведет и все файлы.

Команда начинает работу с текущего каталога.

Для записи в файл достаточно использовать стандартный метод перенаправления, например:

tree -d -R >/tmp/tree.txt

Если вы находитесь в каталоге, скажем /home/user, утилита запишет в файл /tmp/tree.txt все дерево каталогов, начиная с /home/user