Книги, научные публикации

1 Modern Linux - storage resource planing Москва февраль 2006 Алексей Барабанов.

Современный Linux-сервер: как планировать дисковые ресурсы.

Часть 2.

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

Введение.

В первой части обсуждения данной темы [1] на основании анализа эксплуатационного цикла сервера были выдвинуты два принципа (использовать всегда RAID1 вместо обычных разделов диска и перевести максимум объема под управление LVM), исходя из которых, предлагалось производить планирование дисковых ресурсов. Но существует еще одна, и не последняя, цикличность в работе серверов, как и любых компьютеров, которую надо принять во внимание - процесс загрузки. Это неизбежная фаза начинается сразу после включения питания и завершается после выхода системы в рабочий режим. Ключевую роль в ней играет загрузчик. Необходимость существования независимого от операционной системы загрузчика обусловлена именно тем, что надо согласовать уровни представления систем хранения данных с точки зрения BIOS и того, как их представляет ядро ОС. Из двух крайностей, поместить BIOS в ядро или само ядро в BIOS, был выбран технологический компромисс - загрузчик. Обсудим подробнее.

Процесс загрузки.

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

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

В начальный момент времени BIOS, собравший всю доступную информацию о физически подключенных устройствах, производит в определенном порядке перебор систем хранения и поиск на них загрузчика. Управление будет передано первому подходящему. BIOS доступна лишь физическая структура устройств. Все, на что он способен это загрузить первый сектор, проверить наличие специальной сигнатуры и передать управление полученному коду. Главные ограничения: код размещается в объеме сектора (512 байт), выбирается всегда лишь первый сектор. Поскольку BIOS никак не учитывает существование разметки дисков, то загрузчик смело может занимать 510 байт (512 - сигнатура).

Теперь обсудим конечную точку работы загрузчика (но не конечную точку загрузки!).

Загрузчик должен точно так же, как чуть раньше это сделал BIOS, найти следующий программный код, то есть ядро ОС, загрузить его, проверить корректность и передать управление. Естественно, расположение ядра операционной системы и всех необходимых 2 Modern Linux - storage resource planing для загрузки файлов зависит от типа и свойств самой ОС. Хотя в заголовок статьи вынесено утверждение, что рассматривается именно Linux, но это не значит, что вместе с ним на дисковых ресурсах не будут располагаться и другие ОС.

Итак, получили разрыв представлений. Воспользуемся все той же диаграммой переходов в процессе настройки для иллюстрации (Рисунок 1.).

Рисунок 1. Видимость уровней представления на разных стадиях загрузки.

Синим цветом на рисунке обозначено то, что может видеть BIOS, а зеленым то, что должен видеть загрузчик. Между узлами 2 MD и 5 EXT3... изображена двунаправленная стрелка. Как было показано в первой части статьи [1], логическая структура файловой системы, положенной поверх RAID1, не меняется. Благодаря этому можно считать, что если загрузчик обязан понимать файловую систему, то он будет понимать её, размещенную поверх MD. Но это и максимум его понятливости. Иначе говоря, на настоящий момент не представляется возможным разместить всю систему целиком на логических томах LVM. Приходится часть, необходимую для загрузки, все-таки выносить за пределы этой столь удобной системы управления томами данных.

Это утверждение иллюстрируется все тем же RHEL, в котором файлы, участвующие в 3 Modern Linux - storage resource planing загрузке, размещаемые традиционно в /boot, записываются во внешний по отношению к всей системе том, который не подключается в управление LVM.

Вывод. Хотя очень правильно все, что можно, внести внутрь LVM, но приходится мириться с существованием разделов, проинициализированных в последовательности 1 DISK, 2 MD, 3 EXT3... И следующий вопрос: достаточно ли одного только /boot, как считают в компании RedHat, или все-таки надо нечто посущественней? Для этого разберем, как работает загрузчик.

Работа загрузчика.

Linux в силу своей открытости стал весьма консервативной системой, так как каждая его компонента подвергается очень подробному анализу на адекватность назначению. Хотя вместе с дистрибутивом SuSE поставляются четыре загрузчика (Lilo, Grub, Syslinux, Loadlin), но в качестве стандартных, как правило, использовались только два - Syslinux и Grub. Долгое время они развивались, конкурируя друг с другом, и лишь недавно определилось, что будущее именно за Grub. Объясним, почему так.

Опять обратимся к рисунку 1. Посмотрите, загрузчик не обращается к физическим дисковым устройствам, он смотрит только на файловые системы. Именно это свойство, а не что-то иное определило преимущества проекта Grub. Дело в том, что загрузчик должен предоставить оператору выбор путей загрузки. И Grub считывает файл меню, свои кодовые файлы и файлы загружаемых систем, пользуясь ТОЛЬКО собственным драйвером файловой системы и никак не привязываясь к физическим константам устройств. Lilo, являсь исторически более ранним творением, не придерживался такой концепции, почему и вынужден был уступить.

Внимание: Изначально в дистрибутиве SuSE 10.0 поставляется Grub версии 0.96. Этот релиз содержит ошибку. В обновлениях предлагается версия 0.97. В дальнейшем будет применяться именно эта, обновленная версия.

Рассмотрим, как работает Grub. Для этого обратимся к рисунку 2, где наглядно представлен процесс установки и загрузки Grub. Обсуждение будем вести в терминологии Grub.

Итак, в самом начала BIOS считывает код загрузчика из первого сектора диска (1 на рисунке). 512 байт явно не достаточно, чтобы разместить там драйвер файловой системы.

Эта часть загрузчика называется stage1. Её назначение загрузить stage1_5 - специальную фазу, содержащую драйвер файловой системы. Проблема в том, чтобы добиться однозначности размещения этой фазы по отношению к stage1. Это достигается путем записи данной компоненты на нулевую дорожку загрузочного устройства, т.е. вслед за первым сектором, содержащим stage1. В режиме LBA (диски актуальных для серверов ёмкостей в другом режиме просто не работают), на дисковом устройстве размещается сектора в дорожке. То есть уровень линтеллекта stage1_5 может быть повышен до 30Кбайт. Для работы с файловой системой ext3 хватает чуть более 8Кбайт. Иначе говоря, резервы эволюции у проекта Grub еще есть.

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

основную свою компоненту stage2 (3 на рисунке) и файл, содержащий меню, menu.lst (4 на рисунке). Все! Теперь в памяти компьютера работает полностью собранный загрузчик, 4 Modern Linux - storage resource planing который пользуется возможностями файловых систем для поиска всех указанных в меню файлов. Таким путем обеспечивается независимость первых фаз загрузки от конкретного размещения файлов внутри файловой системы. То есть, если модифицировать stage2, или изменить menu.lst, или какие-то из загружаемых файлов, описанных в меню, то при следующей загрузке stage1+stage1_5, как ни в чем не бывало, загрузят новые файлы.

Рисунок 2. Работа загрузчика Grub.

На рисунке 2 показано, как реальное разбиение жесткого диска понимается загрузчиком.

В процессе установки надо указать корень, где размещены все файлы загрузчика. В нашем случае это делается командой root (hd0,1). Установщик определяет тип файловой системы и согласно этому подбирает следующую фазу - e2fs_stage1_5. И далее, остается лишь указать, куда записывать stage1+stage1_5. Это производится командой setup (hd0). После чего нужные компоненты записываются на нулевую дорожку указанного устройства, и в них жестко прошивается размещение и названия остальных файлов stage2 и menu.lst, иначе говоря, первая команда root (hd0,1), указывающая на корень загрузчика. Заметим, что корень, в котором размещается загрузчик, может, и даже очень часто, не совпадать с корнем самой загружаемой системы.

Определим здесь минимум-миниморум того, что должно быть размещено на разделе загрузки, (hd0,1) в нашем случае. Если мы обсуждаем загрузку Linux-системы, то на этом разделе, кроме уже перечисленных файлов загрузчика, нужно разместить ядро и initrd, данные для инициализации виртуального диска, подключаемого в процессе загрузки ядра системы. Примерно так и рассуждают в компании RedHat, когда выделяют /boot в качестве раздела загрузки. Теперь обсудим реальное положение дел.

5 Modern Linux - storage resource planing Эксплуатационные фазы.

Давайте мысленно вернемся к исходным целям вырабатываемых механизмов и способов разметки. Итак, главное - добиться условий для манипуляций с логическими томами и размещенными на них файловыми системами таких, чтобы максимально на сколько возможно оставлять сам сервер в работоспособном состоянии, чтобы для обслуживания не требовалось физического вмешательства (поскольку это несовместимо с автоматизацией и вообще с логикой работы вычислительных систем). Если, как это предложено все в том же RHEL, корневая файловая система размещена на логическом томе LVM, то для преобразований надо будет сначала отмонтировать корень. Конечно, можно просто заявить, что это не понадобиться, так как всегда можно к самому корню подмонтировать нужный объем, взятый все с того же LVM. Примем пока это объяснение. А если возникает необходимость в обновлении используемой системы? А если надо выполнить в системе настройку, результат которой может оказаться не на 100% успешным? Тогда возникает требование иметь на SAS-устройстве второй экземпляр системы со своим независимым корнем. И, загрузив этот второй экземпляр системы, можно выполнить все перечисленные операции.

Состояние сервера, работающего под управлением вспомогательного экземпляра операционной системы, будем называть фазой обслуживания (на диаграмме Out Of Order).

Здесь снова получаем прежнюю проблему. Ведь можно и корень второй системы разместить на LVM, вынеся лишь /boot в отдельный раздел диска. Тогда задумаемся, какая глубина online-преобразований (без отключения) требуется. Если надо оставить возможность перепланировки всего дискового устройства, то разумно ВСЕ данные вспомогательной системы вынести на отдельный раздел. Аналогичное соображение верно и в отношении основной системы.

Наблюдательный читатель спросит: ну хоть /var можно вынести в примонтированный том, и тем самым сократить размер корневого раздела? Конечно можно! Только надо учесть, что в случае проблем с монтированием в /var на чистом корне не будет никаких структур, обеспечивающих работу сервисов - даже /var/run. Поэтому правильной последовательностью будет установка всей системы в единый раздел и потом уже перенос того, что нужно, на другие тома LVM с последующим монтированием их. Такая последовательность установки позволит практически с минимальной потерей функциональности отключать все на лету и соответственно менять. Значит - сэкономить не получится!

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

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

Принцип 4. Все данные, нужные для работы системы в минимальной функциональности, по возможности, надо устанавливать в один корневой раздел. Это увеличит надежность системы и позволит независимым образом манипулировать другими примонтированными разделами.

6 Modern Linux - storage resource planing Следствием этих принципов является то, что возникают все возможности для создания дополнительного резервирования. Кроме использования зеркальных дисковых устройств можно создать зеркальные системы, которые позволят произвести лоткат изменений в случае повреждения одной из них - той, которая была рабочей, - в процессе online обслуживания. Иначе говоря, если один из дублей системы предназначался для создания фазы обслуживания, то, сделав эти дубли идентичными, получаем пару, состоящую из основной и резервной системы. Конечно, здесь не идет речь о полном дублировании всех данных. Обсуждается лишь вопрос о создании дубликата корневого раздела в части, обеспечивающей функционал сервера.

Теперь вернемся к нашим баранам. Итак, размещения лишь /boot на выделенном томе не достаточно, так как это не обеспечит независимой загрузки для манипуляции остальным дисковым пространством. Значит, надо на отдельном разделе, установленном по схеме DISK, 2 MD, 3 EXT3..., разметить всю систему. И кроме того, сделать это дважды, поскольку надо обеспечить еще и фазу обслуживания основной системы. Одновременно с этим получаем бесплатный дубликат рабочей системы на случай неожиданного технического повреждения последней (например из-за ошибки в процессе наложения патчей), то есть фактически добавляем еще и фазу оперативного резерва.

Таким образом, система после загрузки может перейти в одну из трех фаз: рабочую, обслуживания и резерва. Мысль эта не нова. Не могу привести пример из RHEL, но из SuSE - легко! В стандартно создаваемом в процессе установки menu.lst присутствует пункт аварийной загрузки failsafe. Хоть, failsafe и полумера, но культурного шока от моих предложений не должно быть.

А что в результате, спрашивается? Можно обойтись без спасательного CD! И все? Ведь получается, что все равно переключение системы из фазы работы в другие производится в традиционном варианте лишь с консоли. Ну, можно конечно еще и путем редактирования menu.lst, благо, что возможности Grub позволяют это делать без переустановки. Нет, конечно, ради такой чепухи и не стоило бы городить столько. Все это даст эффект лишь в том случае, если настроить систему управляемой загрузки.

Концепция управляемой загрузки.

С точки зрения загрузчика, процесс загрузки системы, безусловно, управляем. Но с точки зрения самой системы он всегда проходит одни и те же фазы загрузки: BIOS - LOADER - одна из эксплуатационных фаз. Выбор конкретной эксплуатационной фазы производится или из консольного меню оператором, или указанием ветки загрузки по умолчанию путем редактирования самого меню. И то и другое представляет собой весьма рукотворный процесс.

Управляемой загрузкой буем считать такой способ настройки, когда выбор нужной фазы работы системы будет происходить автоматически в процессе загрузки. Конечно, для этого в Grub не хватает функциональности. Его исполнительная часть stage2, которая обрабатывает меню, позволяет модифицировать его и даже выполнять какие-то действия с дисковыми устройствами или сетевыми сервисами, занимает от 100 до 200 Кбайт, в зависимости от сборки. Но этого не достаточно. В процедуре управляемой загрузки нужно иметь возможность выбрать эксплуатационную фазу, анализируя параметры в контексте самого сервера, а не загрузчика. Ну, элементарно, например если в ходе анализа потребуется прочитать данные или с LVM, или с удаленного тома NFS, или получить путь 7 Modern Linux - storage resource planing из LDAP, то вряд ли удастся остаться в рамках только пакета Grub для обеспечения такой функции управления загрузкой.

Итак, обслуживание стадии управления загрузкой будет производится Linux как универсальной платформой. Присвоим новой фазе работы сервера название служебной (на диаграммах Stuff). Это проходная фаза, в которой по некоторым критериям будет выбрана следующая фаза загрузки, произведена соответствующая коррекция и далее произведена перезагрузка. В Grub существует механизм выбора пути загрузки по содержимому специального файла default, который записывается утилитой grub-set-default. Хотя можно и просто менять текст самого menu.lst.

Но чтобы данная функциональная схема запустилась, надо обеспечить назначение служебной фазы, как пути загрузки по умолчанию, для следующей перезагрузки после запуска каждой из других фаз - пунктов меню. Можно воспользоваться все той же утилитой grub-set-default, или так же менять содержимое menu.lst. Но в Grub есть специальный оператор (savedefault), который обеспечивает запись нужного значения прямо из stage2, то есть до передачи управления на загружаемую ОС, которая в общем случае может быть и несовместима с утилитой grub-set-default.

Получается, что кроме уже перечисленных двух систем (одна основная, другая резервная) надо создать еще и третью? Нет, достаточно использовать одну из уже имеющихся, но в специальном режиме. Как это сделать, покажем на примере чуть позже. На примере же и проиллюстрируем, как планируется диаграмма переходов состояний сервера в процессе загрузки.

А сейчас зададимся вопросом, а не ересь ли предлагается здесь - создание специальной инсталляции Linux только для обеспечения загрузки? Нет! Есть аналог предложенного решения. Известен в миру как EFI (Extensible Firmware Interface). Изначально он создавался как новый формат модульного заменителя традиционного BIOS. Но в результате получилось, что такой универсальный инструмент может грузить и ОС, используя свои сильно расширенные возможности. Для обеспечения процесса загрузки с помощью EFI системы Linux используется компонента ELILO (программа в формате EFI), которая читает все загружаемые файлы со специального системного раздела, размеченного в FAT. Объем такого раздела небольшой по нынешним меркам - 128Мбайт, как рекомендовано. На нем должны располагаться и ядра, и initrd, и все, что может понадобиться, как загрузчику ELILO, так и другим компонентам EFI, список которых не ограничивается лишь драйверами и диагностическими утилитами. Но факт остается фактом: то, до чего еще не додумались разработчики проприетарного EFI, легко реализуется на самом Linux.

Пример управляемой загрузки.

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

Поставим задачу следующим образом. Нужно создать универсальную рабочую станцию, которая будет автоматически загружиться как Linux-станция, Windows-станция и X 8 Modern Linux - storage resource planing терминал. Согласно нашей концепции будут также реализованы дополнительные состояния - служебное и состояние обслуживания. Полная диаграмма переходов состояний, начиная с запуска Grub, будет выглядеть, как представлено на рисунке 3.

Рисунок 3. Изменение состояний рабочей станции в процессе управляемой загрузки.

Зеленым цветом обозначены узлы, соответствующие рабочим состояниям, желтым - служебные, красным - состояние обслуживания. Рабочая станция пребывает в состояниях обслуживания и служебном в течение времени, необходимого на выполнение запрограммированных задач. А вот пребывание в рабочих состояниях ограничивается лишь целевой необходимостью и завершается командой оператора на перезагрузку или выключение, но также может быть инициировано удаленным запросом с центрального сервера, управляющего всей сетью подобных рабочих станций. Естественно, технология такого запроса полностью определяется платформой, которой этот запрос должен управлять. Например, для того чтобы выключить MS Windows XP удаленно с Linux сервера, можно воспользоваться специальным запросом MS RPC:

> rpcclient -c shutdowninit -U username%password ip-address где username и password соответствуют бюджету администратора на компьютере с адресом ip-address, где будет запущена процедура выключения (которая, кстати, не сможет автоматически завершить работающие программы, увы).

Меню Grub для обеспечения требуемой смены состояний можно построить следующим образом:

# cat /boot/grub/menu.lst 9 Modern Linux - storage resource planing color white/blue black/light-gray default saved hiddenmenu timeout # title Out Of Order root (hd0,1) kernel /boot/vmlinuz root=/dev/sda2 vga=0x332 selinux=0 splash=0 showopts initrd /boot/initrd savedefault # title Linux root (hd0,1) kernel /boot/vmlinuz root=/dev/sda2 vga=0x332 selinux=0 splash=0 showopts initrd /boot/initrd savedefault # title Windows root (hd0,2) chainloader + makeactive savedefault # title Terminal bootp root (nd) kernel /lts/pxe/vmlinuz.ltsp root=/dev/ram0 rw init=/linuxrc initrd /lts/pxe/initrd.lts savedefault # title Stuff root (hd0,1) kernel /boot/vmlinuz root=/dev/sda2 vga=0x332 selinux=0 tonextboot splash=0 showopts initrd /boot/initrd savedefault # Это, конечно же, один из возможных вариантов, и многие параметры надо назначить согласно используемому оборудованию и принятым установкам работы. В частности, выше видно, что все состояние, обслуживаемые Linux, совмещают один экземпляр системы (так как цель демонстрации лишь управляемая загрузка). Пункты меню, соответствующие основным состояниям, более-менее однозначны: № 1 Linux и № Windows соответствуют стандартным способам запуска этих систем из Grub. № 3 Terminal запускает клиента LTSP путем загрузки ядра и initrd с ресурса tftp, который указывается по протоколу DHCP. Для того чтобы сработала команда bootp, надо вместо stage2, устанавливаемой в ходе стандартной процедуры, разместить в корне Grub stage2, специально собранную для работы с сетью:

# cp /usr/lib/grub/stage2.netboot /boot/grub/stage При этом выполнение всех остальных команд меню не пострадает. Пункты меню № 4 Stuff и № 0 Out Of Order во всем практически подобны стандартному режиму запуска Linux на уровень 3. Но для правильного их функционирования надо запрограммировать специальную обработку этих режимов в процессе инициализации соответствующего уровня. Продемонстрируем, как это сделать для служебного режима, поскольку он является ключевым для реализации всей схемы.

Будем использовать в качестве управляющего признака содержимое файла, размещенного на локальном http-ресурсе. Далее принимаются стандарты SuSE на расположение таких файлов. Например, сделаем так: если следует запустить станцию с адресом 192.168.0.166 с использованием пункта меню Grub с номером 1, то запишем этот номер в файл, названный 10 Modern Linux - storage resource planing по IP-адресу нужной станции (действия производятся на http-сервере):

# echo 1 >/srv/www/htdocs/192.168.0. Это значение можно прочесть со станции с помощью wget, lynx или curl, обратившись по адресу если именно такой адрес у нашего локального http-ресурса. Получив значение нового рабочего состояния, скрипт устанавливает параметры следующей загрузки, используя утилиту grub-set-default.

Скрипт, который будет анализировать параметр управления загрузкой, назовем tonextboot.

Для того чтобы он вызывался автоматически, придется поместить его в процесс стартовой инициализации соответствующего уровня, в нашем случае уровня 3:

# cp tonextboot /etc/init.d # insserv tonextboot Но чтобы скрипт знал, когда запускать систему в служебном режиме, добавим специальный параметр, который будем передавать через Grub ядру в командной строке так, чтобы потом можно было проверить его наличие через /proc/cmdline. Примем таким параметром управляемое слово tonextboot. Если этого слова нет, то скрипт считает, что это какой-то иной режим запуска, а не Stuff. Если же такое слово обнаруживается, то следует выполнить действия, указанные на рисунке 3. Полный текст скрипта, сделанный по стандартам SuSE приведен на врезке Текст 1. Чтобы скрипт правильно встал в порядок загрузки, указано, что для его работы требуется инициализированный сетевой уровень.

#!/bin/sh # ### BEGIN INIT INFO # Provides: tonextboot # Required-Start: network # Should-Start:

# Required-Stop: network # Default-Start: # Default-Stop:

# Description: Check and set next boot way ### END INIT INFO. /etc/rc.status rc_reset NULL=/dev/null SRV=" #VERB= DEF= abort() { [ "1${VERB}" != "1" ] && { echo ;

echo -n "Error: $1" ;

} rc_status -u rc_exit } default() { [ "1${VERB}" != "1" ] && { echo ;

echo -n "Error: $1" ;

} BOOT=$DEF echo -n " to $BOOT" $GRUB $BOOT rc_status -v /sbin/shutdown -r now rc_exit } echo -n "Check and set next boot way" 11 Modern Linux - storage resource planing case "$1" in start) STUFF=$(cat /proc/cmdline | grep tonextboot) [ "1${STUFF}" == "1" ] && { abort "use only for stuff level!" ;

} CURL=`which curl 2>$NULL` [ "1${CURL}" == "1" ] && { abort "need curl!" ;

} GRUB=`which grub-set-default 2>$NULL` [ "1${GRUB}" == "1" ] && { abort "need grub-set-default!" ;

} HOST=$(hostname -i | grep 192.168) [ "1${HOST}" == "1" ] && { default "cant resolve address!" ;

} BOOT=$(${CURL} --max-filesize 2 -s ${SRV}${HOST} | grep "[[:digit:]]") [ "1${BOOT}" == "1" ] && { default "cant get boot way!" ;

} echo -n " to $BOOT" $GRUB $BOOT rc_status -v /sbin/shutdown -r now ;

;

*) rc_status -s ;

;

esac rc_exit Текст 1. Скрипт tonextboot.

Скрипт очень простой и прозрачный по смыслу. В нем есть обработка только одной непредвиденной ситуации - если скрипт не может вообще никак лузнать следующее состояние сервера. Тогда принимается политика по умолчанию, которая управляется переменной DEF.

Нельзя не сказать и о том случае, когда grub-set-default будет вызван с номером, превышающем число возможных ветвлений меню Grub. Тогда система запустится с параметрами нулевого пункта меню. Это надо учитывать при планировании порядка размещения состояний в меню Grub.

Все перечисленные настройки, включая модификацию stage2, выполняются без переустановки Grub. Затем производится начальная инициализация grub-set-default 4 и после перезагрузки система станет работать в зависимости от того уровня, что назначен на сервере www.office.localnet для данной станции.

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

Сопутствующие вопросы.

Рассмотрение темы планирования дисковых ресурсов не будет полным, если не коснуться вопросов надежности программных уровней представления данных (LVM, MD и проч.) и выбора типа файловой системы. Вопреки традиционному подходу, не будем придавать этим вопросам статус основополагающих. И вот по какой причине.

В отношении LVM существует расхожее бытовое мнение о, якобы, низкой ее надежности, основанное на том факте, что после повреждения структуры LVM практически невозможно восстановить данные файловых систем, созданных внутри логических томов. Это неверно 12 Modern Linux - storage resource planing построенная логическая цепочка рассуждений. По аналогии, многие люди считаю опасными самолеты, на том основании, что, мол, летаю быстро и высоко, и при падении выживших крайне мало, но при этом забывают, что статистика свидетельствует, что обычный автотранспорт гораздо опаснее. Но и это не самое главное. В таком рассуждении подменяется объект. Цикл эксплуатации состоит из времени наработки на отказ, отказом и периодом восстановления. Так вот, надежность всецело определяется временем наработки на отказ. И это время не зависит от сложности самой программной системы, а лишь от надежности оборудования. Причина в том, что в настоящее время в ЭВМ применяются детерминированные алгоритмы. То есть вне зависимости от цепочки преобразований пара одинаковых запросов вернет эквивалентные данные. Безусловно, чем сложнее преобразования, тем сложнее их реконструкция на этапе восстановления. Но, во-первых, это уже не имеет отношения к надежности, а, во-вторых, кто сказал, что восстановление сложных систем надо производить примитивными способами?

В отношении MD и остальных программных систем все аналогично. Есть лишь те проблемы, что каждая из таких систем вводит в работу ряд параметров, например название MD устройства, имя группы LVM, и при физической модификации дисковых устройств возможны конфликты по этой причине. Наличие вспомогательной системы, кроме основной, позволит модифицировать все подобные параметры у основной системы, чтобы избежать конфликта.

Самый спорный вопрос, это, конечно же, предпочтения типа файловой системы. Очень часто этот вопрос перетекает из области рациональной оценки в область вкуса, привычек или политических предпочтений. А как же иначе? Ведь, если бы существовало однозначное решение, так все менее популярные проекты просто прекратили бы развиваться. Значит, в каждой из файловых систем есть собственные преимущества.

Попробуем решить спор тривиальным тестированием с помощью bonnie (Таблица 1).

Условия полностью совпадают с теми, что были в первой части статьи [1]. Только параметром будет тип файловой системы (перечислены в верхней строке). Режимы тестирования указаны в самом левом столбце. В перекрестьях замеренные результаты в Кбайт в секунду, рядом с которыми изображены индексы отклонения от средней по данному тесту величины.

ext3 reiserfs reiserfs4 xfs jfs 1 2 3 4 Символьная запись 1 47362 - 1,01 47965 - 1,02 37533 - 0,80 49783 - 1,06 52083 - 1, Блочная запись 2 60396 - 1,01 66731 - 1,12 51754 - 0,87 61549 - 1,03 57912 - 0, Перезапись 3 21618 - 0,95 22360 - 0,98 22116 - 0,97 23365 - 1,03 24225 - 1, Символьное чтение 4 21791 - 0,82 23956 - 0,90 29647 - 1,12 28199 - 1,06 28893 - 1, Блочное чтение 5 53288 - 0,99 52851 - 0,98 53963 - 1,00 54159 - 1,01 54350 - 1, Итоговая оценка 6 2 - 0,96 2 - 1,00 1 - 0,95 5 - 1,04 4 - 1, Таблица 1. Зависимость скорости доступа от типа файловой системы.

Для наглядности представим результаты в графической форме в виде столбчатой диаграммы (рисунок 4). И убедимся, что серьезного преимущества нет ни у одного из форматов.

13 Modern Linux - storage resource planing Рисунок 4. Зависимость скорости доступа от типа файловой системы.

Тогда определим для каждой из систем число индексов, превосходящих 1, рассчитаем средний индекс и запишем все это в итоговой строке (строка 6 в таблице 1). Теперь уже можно установить, что лучшие результаты у xfs и jfs, худший - у reiserfs4, а вот те файловые системы, что зачастую принимаются в качестве стандартных в инсталляторах лиз коробки, ходят в явных середнячках (и даже не в троечниках!). Хотя отклонения не превышают 5%. Иначе говоря, нет иного способа объяснить выбор форматов ext3 и reiserfs в качестве стандартов, как учетом их большей отработанности (например, в jfs значительное число возможностей пока имеет статус экспериментальных) и большей историей использования.

Тем более, вспомним, что выбор типа файловой системы для нас актуален лишь относительно. Используя основную систему, можно поменять формат файловых систем, размещенных в LVM, почти на лету: создать снапшот LVM, произвести резервное копирование, создать новый логический том, разметить его в новом формате, синхронизировать данные и перемонтировать. Лишь две последние операции потребуют кратковременного отключения. Даже формат основной системы можно поменять, используя вспомогательную систему. А потом и на ней изменить разметку, воспользовавшись уже основной.

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

Заключение.

Обсуждение вопросов, связанных с темой планирования дисковых ресурсов, можно считать завершенной. Были сформулированы четыре принципа, которые следует учитывать при создания конкретного серверного решения. Проиллюстрированы разнообразные 14 Modern Linux - storage resource planing технологические приемы, сопутствующие предложенным технологиям. Но, безусловно, все вышесказанное носит рекомендательный характер. Не стоит забывать, что дисковые подсистемы и вопросы, их окружающие, являются лишь частью, хотя и достаточно важной, всех задач, которые решаются в ходе построения прикладного сервера. И конечный выбор способа, которым надо разбить дисковые устройства на разделы, полностью определяется назначением самого сервера. О том, какие преимущества можно получить, используя предложенный здесь подход, обсудим в продолжение цикла.

Ссылки на источники.

1. Барабанов А. Современный Linux-сервер: как планировать дисковые ресурсы. Журнал Системный администратор, №1 за 2006 год.

   Книги, научные публикации