Прежде, чем мы начнем конфигурировать различные аспекты работы сети, нам необходимо проверить наличие некоторых необходимых параметров в ядре. Обратитесь к главе Глава 28, Компиляция ядра для получения дополнительной информации о конфигурации, компиляции и установке ядра. Здесь мы рассмотрим процесс конфирурирования ядра, касательно параметров сети. В качестве примера мы будем использовать файл конфигурации i386/GENERIC. Конфигурационный файл для других платформ содержат подробные комментарии и подсказки. Помимо представленной здесь информации, каждая опция содержит страницу руководства options(4) , так же как и драйверы устройств, например tlp(4). Читать дальше
Эта глава разъясняет различные аспекты работы сети. Что предполагает помощь начинающим людям с небольшими познаниями сети. Она соотоит из трех больших частей. Мы начнем с рассмотрения главной части работы сети и основных концепций. Затем, во второй части, мы рассмотрим в деталях настройки различных типов сети и в третьей части раздела работы сети изучим некоторые «продвинутые» аспекты, для углубления познаний, полученных в первых двух разделах. Читать дальше
19.1. Создание установочной/загрузочной дискеты i386
Возможно, Вы захотите изготовить собственные загрузочные дискеты для платформы i386, вместо того, чтобы использовать уже прекомпилированные. Читать дальше
Необходимо убедиться, что PPPoE поддерживается ядром. Для этого выполните команду:
-bash-3.00$ ifconfig -C
bridge vlan gif gre tun tap strip sl pppoe ppp lo
Если в строке вывода не обнаружится упоминания о pppoe, то необходимо перекомпилировать ядро, добавив туда строку:
pseudo-device pppoe
Проверка соединения
Прежде чем настраивать на машине автоматическое соединение, давайте попробуем все сделать в ручном режиме. В случае проблем это позволит нам быстро обнаружить и устранить неисправность.
Сначала мы создаем интерфейс pppoe и назначаем ему произвольный адрес, так как в дальнейшем он будет изменен в ходе установления сессии PPP. Поскольку интерфейс еще не настроен, активировать его не будем.
ifconfig pppoe0 create
ifconfig pppoe0 inet 0.0.0.0 0.0.0.1 down
Сейчас привяжем интерфейс pppoe к соответствующей сетевой карте, например к той, к которой подключен DSL модем, или которая смотрит в сеть провайдера.
ifconfig rtk0 up
pppoectl -e rtk0 pppoe0
Теперь нам понадобятся наши аутентификационные данные. Введем их воспользовавшись следующей командой (учтите, что для закрытия специальных символов используются одинарные кавычки):
В данном случае, XXX это имя пользователя, а YYY – его пароль. Параметр hisauthproto=none указывает PPP, что нет необходимости подтверждать подлинность провайдера, так как большинство из них не предоставляют такой возможности. Если провайдер осуществляет авторизацию по протоколу CHAP, то необходимо установить параметр myauthproto=chap.
Мы готовы к подключению. Так как что-то может пойти неправильно, мы ограничим количество повторных попыток установить соединение:
pppoectl pppoe0 max-auth-failure=1
И активируем интерфейс:
ifconfig pppoe0 up
Поскольку мы не задействовали режим отладки, то на консоли мы не увидим ровным счетом ничего. Работу сессии PPPoE мы можем проверить следующим образом:
В этом примере у нас отображается рабочая сессия PPPoE (state = session). Если у вас указано другое состояние, то проверьте правильность указания регистрационных данных или доступность сервера. Ошибки будут отображаться как увеличение значения счетчиков PADI или PADR. Попробуйте указать service name (через опцию -s в pppoectl) или access concentrator name (через опцию -a в pppoectl), если эти данные необходимы, то провайдер должен вам их предоставить. Для получения дополнительной информации, обратитесь к странице руководства man pppoectl(8).
После того как сессия PPPoE была установлена, проверим правильность выделения IP адреса сервисом PPP:
Как мы видим, подключение установлено правильно, поскольку мы видим свой адрес и адрес удаленного хоста (естесственно, у вас будут другие адреса). Если вы не видите подобной картины, то скорее всего, вы неверно указали аутентификационные данные PPP.
Установка постоянного соединения
После того, как мы проверили работу соединения, настроим машину на автоматическую установку сессии.
Для этого нам придется написать несколько сценариев и внести изменение в некоторые файлы конфигурации. В зависимости от тарифного плана, вы можете предпочесть постоянное соединение или соединение по требованию.
Независимо от тарифного плана, провайдер должен вам предоставить адреса DNS серверов, которые необходимо внести в /etc/resolv.conf.
Постоянное соединение
В этом случае мы устанавливаем соединение и оставляем его открытым сколь угодно долго, восстанавливая связь при обрыве.
Создадим файл /etc/ifconfig.pppoe0 следующего содержания:
create
# Mark the physical interface used by this PPPoE interface up
! /sbin/ifconfig rtk0 up
# Let $int use rtk0 as its Ethernet interface
! /sbin/pppoectl -e rtk0 $int
# Configure authentication
! /sbin/pppoectl $int myauthproto=pap 'myauthname=XXX' 'myauthsecret=YYY' hisauthproto=none
# Configure the PPPoE interface itself. These addresses are magic
# meaning we don't care about either address and let the remote
# ppp choose them.
0.0.0.0 0.0.0.1 up
Выставьте права доступа таким образом, чтобы прочитать этот файл мог только пользователь root.
В файл /etc/ppp/ip-up внесите:
#! /bin/sh
/sbin/route add default $5
В файл /etc/ppp/ip-down внесите:
#! /bin/sh
/sbin/route delete default $5
Также убедитесь, что прочитать эти файлы может только пользователь root.
В заключение, добавим следущую строку в /etc/rc.conf:
ifwatchd=YES
Дело сделано. Обратите внимание, что загружается демон ifwatchd (выполняющий сценарии ip-up и ip-down). Проблема может заключаться в том, что маршрут по умолчанию может быть установлен после старта сетевых демонов, что приведет к некорректной их работе. Для устранения этой досадной ошибки рекомендую использовать подобный сценарий ip-up:
В данном примере мы устанавливаем соединение при необходимости передать данные и разрываем его при простое.
Главные отличия от постоянного соединения заключаются в следующем:
Флаг link1 на интерфейсе pppoe0
Лимит бездействия (в данном примере 60 секунд)
Конфигурация маршрутизации, когда первый пакет идет на интерфейс pppoe0, в то время, как соединение еще не установлено
Создадим файл /etc/ifconfig.pppoe0:
create
# Mark the physical interface used by this PPPoE interface up
! /sbin/ifconfig ne0 up
# Let $int use ne0 as its Ethernet interface
! /sbin/pppoectl -e ne0 $int
# Configure authentication
! /sbin/pppoectl $int idle-timeout=60 myauthproto=pap 'myauthname=XXX' 'myauthsecret=YYY' hisauthproto=none
# Configure the PPPoE interface itself. These addresses are magic
# meaning we don't care about either address and let the remote
# ppp choose them.
0.0.0.0 0.0.0.1 link1 up
! /sbin/route add default -iface 0.0.0.1
Использовать ifwatchd в этой конфигурации нет необходимости, поскольку мы уже задаем маршрут по умолчанию. Если вам необходимо получать уведомления о изменениях IP адресов или состояния соединения, то вы можете сконфигурировать ifwatchd и использовать/etc/ppp/ip-up и/etc/ppp/ip-down.
Установка NAT с MSS-clamping
Некоторые машины с ненастроенной системой фильтрации пакетов пытаются использовать Path-MTU-Discovery, в то время как пакетный фильтр отбрасывает все ICMP пакеты. Вполне вероятно, что вам придется общаться с такими системами, при необходимости получить от них данные.
В связи с этим, предать большие обьемы данных машине, подключенной через PPPoE, будет затруднительно. Для решения этого вопроса мы пошлем маленькое значение MSS (maximum segment size) во время установки сессии TCP. Для этого нам необходимо установить sysctl переменную net.inet.tcp.mss_ifmtu, добавив в /etc/sysctl.conf следущую строку:
# Obey interface MTUs when calculating MSS
net.inet.tcp.mss_ifmtu=1
В этом случае, в правилах NAT вашего маршрутизатора, имеющего связь с миром через PPPoE необходимо указать следущие строки:
Если вы не используете NAT, то добавьте такое правило:
map pppoe0 x.x.x.x/24 -> 0/0 mssclamp 1440
В вышеприведенных примерах MTU принимается равным 1492 байтам. Учитывая смещение в 52 байта, укажите свое MTU, например 1408 для MTU 1460 байта. Обратите внимание: теоретически правильное значение для вышеупомянутого примера было бы 1452 байта (минимальное значение PPPoE MTU, заголовок TCP и максимум 0×40 байтов опций TCP).
Аббревиатура CARP расшифровывается как Common Address Redundancy Protocol. Основной целью этого протокола является использование одного IP адреса в пределах одного сегмента сети несколькими машинами. CARP является свободной, безопасной альтернативой протоколам Virtual Router Redundancy Protocol и Hot Standby Router Protocol.
CARP позволяет выделить группу хостов в сегменте сети и назначить ей один IP адрес. Такая группа называется «redundancy group» (группа избыточности). В пределах этой группы, один из хостов становится «главным», а остальные обозначаются как «резервные». В каждый момент времени мастер-хост отвечает на ARP-запросы к назначенному IP адресу и обрабатывает трафик, идущий к этому адресу. Каждый хост одновременно может принадлежать к нескольким группам.
Одним распространенным случаем использования CARP является создание избыточности на брандмауэрах. Виртуальный IP, который назначен на группу избыточности, указан на клиентских машинах в качестве шлюза по умолчанию. В случае отказа брандмауэра, выполняющего роль мастера, резервный брандмауэр возмет этот IP адрес и продолжит обслуживание клиентов.
При использовании CARP снижаются требования к аппаратному обеспечению отказоустойчивых систем. Дорогое оборудование окажется бессильным к выдернутому шнуру питания или перед администратором, случайно отправившим сервер в перезагрузку. CARP также облегчает процесс обновления программного обеспечения, так цикл обновления и перезагрузки прозрачен для пользователей, становится проще и процесс тестирования программного или аппаратного обеспечения – вы всегда можете положиться на резерв, пока не устраните проблему.
Однако, есть ситуации, когда CARP не может помочь. Дизайн CARP требует, чтобы члены одной группы физически находились в одной подсети с одним статическим IP адресом, хотя с введением директивы carpdev необходимости назначать адрес на физический интерфейс нет. Сервисы, требующие постоянного соединения с сервером (такие как SSH и IRC) не могут быть прозрачно переброшены в случае отказа и потребуют переподключения. CARP не может синхронизировать данные между приложениями.
Veriexec является системой проверки целостности файлов NetBSD.
Она входит в состав ядра, поэтому может обеспечить защиту даже
в случае компрометации учетной записи пользователя root.
Эта глава применима только к версии NetBSD 3.0 и выше.
18.1. Как это работает
Veriexec работает загружая файл спецификации, также
называемый также файлом сигнатур,
в ядро. Этот файл содержит информацию о файлах, мониторинг
которых проводится, в виде хэшей и различные флаги, которые
мы обсудим позже.
В настоящий момент поддерживаются следующие алгоритмы Veriexec: MD5, SHA1, SHA256, SHA384, SHA512, and RMD160.
18.2. Файл сигнатур
Запись в фале сигнатур выглядит следующим образом:
/path/to/file algorithm fingerprint flags
Где первое поле представляетс собой абсолютный путь до файла,
далее указан алгоритм и ASCII отпечаток (контрольная сумма).
18.3. Генерирование контрольной суммы
Вы можете сгенерировать контрольную сумму ASCII
для каждого алгоритма используя слкдующие утилиты:
Таблица 18.1. Veriexec fingerprints tools
Алгоритм
Утилита
MD5
/usr/bin/md5
SHA1
/usr/bin/sha1
SHA256
digest sha256 (из
pkgsrc)
SHA384
digest sha384 (из
pkgsrc)
SHA512
digest sha512 (из
pkgsrc)
RMD160
/usr/bin/rmd160
Для примера, создадим контрольную сумму MD5 для /bin/ls:
С каждой записью может ассоциироваться несколько флагов.
В настоящее время флаги описывают метод обращения к файлу, которому
соответствует запись. Обратите внимание, что этот тип доступа
применим только в 2 уровне доступа (режим IPS) и выше.
Типы доступа могут быть «DIRECT»,
«INDIRECT» и «FILE».
Метод DIRECT
указывает на прямое выполнение и не вызывается как интерпретатор
для некоего сценария или открываемого текстовым редактором.
К большинству используемых вами файлов стоит обращаться именно
так:
%ls /tmp%cp ~/foo /tmp/bar%rm ~/foo
Метод INDIRECT
означает косвенное выполнение файла, например, для интерпретации
сценария. Это происходит, когда сценарий в первой строке
содержит #!. Для примера, у нас усть скрипт, в первой строке
содержащий:
#!/bin/sh
И вы запускаете его:
%./script.sh
В этом случае происходит косвенный вызов /bin/sh для интерпретации
скрипта.
Запись FILE
указывает на невыполняемый (или, который не должен быть выполняемым)
файл. Это могут быть библиотеки, файлы конфигурации и т.д.
Вот несколько примеров записей в файле сигнатур Veriexec:
Veriexec позволят вам определить несколько вариантов доступа к файлу.
Для примера, /usr/bin/perl может быть вызван
как интерпретатор, так и в качестве самостоятельной программы.
Для этого мы должны указать:
Сценарии оболочки, использующие #! для «выполнения»
также требуют указания двух типов доступа: «DIRECT» для
выполнения и «FILE» для того, чтобы ядро могло подать
содержимое скрипта интерпретатору:
Для облегчения создания фала сигнатур и повышения читабельности,
Veriexec может понимать следующие псевдонимы:
Таблица 18.2. Псевдонимы типов Veriexec
Alias
Expansion
PROGRAM
DIRECT
INTERPRETER
INDIRECT
SCRIPT
DIRECT, FILE
LIBRARY
FILE
Примерный сценарий для генерации контрольных сумм доступен в /usr/share/examples/veriexecctl. После
генерации файла сигнатур, который сохраняется в /etc/signatures, а включение Veriexec
осучествляется через rc.conf:
veriexec=YES
18.4. Уровни доступа
С тех пор, как люди заинтересовались использованием
Veriexec для различных целей, мы определили четыре уровня
доступа, называемые режимами «learning»,
«IDS», «IPS» и «lockdown».
На уровне доступа 0,
режиме learning, Veriexec будет действовать пассивно и только предупреждать
о любых аномалиях. При обьединении с уровнем 1, может оказаться
полезным при отладке файла сигнатур. На этом уровне, в отличие от
остальных, вы можете загружать новые записи в ядро.
На уровне доступа 1,
режиме IDS, будет запрещаться доступ к файлам с несоответствующей
контрольной суммой. Этот режим больше всего подходит пользователям,
которые предпочитают просто запретить доступ к файлам, которые
могут быть модифицированы злоумышленником.
Уровень доступа 2, режим IPS,
предпринимает шаги по защите файлов. В дополнение к предотвращению
доступа к файлам с несоответствующей контрольной суммой,
закроется доступ на запись и удаление защищаемых файлов и
будет организовано ведение журналов доступа к этим файлам.
Режим блокировки (уровень доступа 3)
может использоваться в критических ситуациях, например машин специального
назначения, или последней линии обороны после компрометации системы,
что-бы воспрепятствовать злоумышленнику удалить следы взлома.
будет запрещено создание новых файлов и запрещен доступ к файлам, не
контролируемых Veriexec.
Мы рекомендуем выполнить первый запуск Veriexec в режиме 0 и
отлаживать в режиме 1, для точной подстройки файла сигнатур,
удостовериться в правильной работе приложений и только после этого
повышать уровень. Для автоматической установки уровня доступа
после перезагрузки вы можете использовать /etc/sysctl.conf:
kern.veriexec.strict=1
18.5. Конфигурация ядра
Для использования Veriexec необходимо, кроме создания файла сигнатур,
обеспечить поддержку в файле конфигурации ядра: (например /usr/src/sys/arch/i386/conf/GENERIC.local):
options VERIFIED_EXEC
Затем, нам необходимо установить поддреживаемые алгоритмы
хэширования:
В этой главе рассматриватриваются вопросы повышения
производительности системы путем более тонкой настройки
различных параметров. В принципе, эта область охватывает
профессиональную сферу и администратора системы и системного
программиста. Искусство тонкой настройки очень старо и
призвано повысить эффективность работы без увеличения
мощности оборудования и может относиться и к NetBSD и к
самому серверу и в принципе, даже к пылесосу.
17.1.1.1. Что такое оптимизация производительности?
После загрузки системы автоматически начинает
выполняться довольно большое количество программ.
Пользователь, начав работать с системой, запускает свои
программы и нашей задачей является повышение производительности
операционной системы под наши конкретные нужды.
Самым распространенным мнением является то, что
«настройка» – это уменьшение размера ядра или увеличение
скорости. На самом деле, это только некоторые из аспектов,
которые нам придется рассмотреть, для того, чтобы привести NetBSD в оптимальное
состояние.
Хорошим примером будет установка параметров файловой
системы. Для системы, где велико количество маленьких
файлов(допустим, репозиторий исходных текстов), администратор
может увеличить число inodes.
Настройка обычно заключается в обнаружении и устранении
критических параметров. В большинстве случаев критические
ситуации являются побочным явлением, например, Mozilla
очень плохо обрабатывает java-апплеты, что может привести
к повышенной нагрузке на центральный процессор или размер
сервера rsynced начинает расти и расти.
17.1.1.2. Когда делать настройку?
Настраивать систему необходимо довольно небольшой
группе пользователей. GENERIC ядро работает прекрасно
и конфигурация позволяет использовать его для самых
разнообразных задач. Если же точная настройка все-таки
необходима, то необходимо четко себе представлять, что
вы будете делать. Настройка обычно делается после
внезапной потери или постепенного снижения производительности,
когда неприятные последствия уже наступают. Давайте не
будем учиться на своих ошибках и рассмотрим основные
методы настройки.
Примером настройки системы может служить желание
получить систему с малым временем перезагрузки. Необходимо
в таком случае как только можно сильнее урезать ядро,
убедившись, что в состав его не входят лишние драйвера(и
даже драйвера присутствующих, но неиспользуемых устройств(lp),
отказаться от запуска дополнительных сервисов. В результате
время загрузки можно сократить почти на две трети, что
при повседневной работе является прекрасным результатом.
17.1.1.3. Что не рассматривается в этом документе
Прежде, чем приступить непосредственно к материалу
главы, хотелось бы оговорить, что здесь не будет рассмотрено.
Это руководство касается только ядра NetBSD, то есть файлы
конфигурации сторонних программ затронуты не будут, так
как про это можно писать до бесконечности и у них, в
большинстве случаев, имеется собственная документация.
17.1.1.4. Используемые примеры
Так как имеется обширная документация на страницах
руководства man, то будут рассмотрены только используемые
в каждом конкретном примере опции и аргументы. В некоторых
случаях материал для краткости усечен или не полностью
описан вследствие простоты. Например, не будет описываться
каждый драйвер ядра в отдельности, однако методика
определения необходимых драйверов будет рассмотрена. Не
стоит принимать этот раздел как непосредственную инструкцию,
это всего лишь учебное пособие.
17.2. Общие вопросы настройки
Тонкая настройка системы не является таким уж сложным
делом, просто заняться этим стоит до того, как
«началось». Настроить сервер до его ввода в
строй проще, чем во время простоя.
17.2.1. Конфигурация системы
Конечно, первоначальная установка системы имеет огромное
значение, так как на этом этапе можно допустить незначительную
ошибку, которая в последствии приведет к неожиданным
проблемам.
17.2.1.1. Файловая система и диски
Размещение файловых систем на дисках – очень важный
вопрос. На системах с аппаратным RAID это не так критично,
но большое число пользователей NetBSD работают с устаревшим
оборудованием, где просто нет RAID. Хорошей идеей будет
размещение / в начале диска, но если
дисков несколько? Стоит ли выделить в отдельный раздел /usr? Будет ли интенсивно использоваться /usr/pkgsrc? Подумайте перед началом
установки над этими вопросами.
17.2.1.2. Конфигурация раздела подкачки
Есть три теории вычисления размера раздела подкачки
и около пятидесяти о разбиении файла подкачки с расстановкой
приоритетов. Каждая теория имеет свои собственные формулы
расчета, например для HP-UX с установленной на нем Oracle
использует формулу:
2.5 GB * Number_of_processor
На самом деле, здесь все зависит от размера и
интенсивности использования баз данных, для примера, если
база данных распределенная, то форма будет не верна.
Следующий подход к расчету размера раздела подкачки
хотя и выглядит несколько странным, но не лишен определенного
смысла. Суть его в том, чтобы по возможности при расчетах
опираться на объем памяти, который необходим для работы
системы. Например, как-нибудь так:
Посчитайте общее количество необходимой памяти
при одновременном запуске всего, что вам может
потребоваться. Это базы данных, web серверы и так
далее.
Добавьте несколько мегабайт про запас.
Вычтите значение RAM из результата.
Если получившийся остаток превышает размер RAM в три
и более раза, то рассмотрите возможность увеличения RAM.
Конечно, есть проблема в определении того, что может
потребоваться и сколько памяти это займет, Другой недостаток
этого метода – возможные ошибки в программном обеспечении.
Например браузер Netscape, который в некоторых своих
версиях имел тенденцию к разрастанию. Поэтому – чем больше
резерва, тем больше времени на убийство процесса.
Не на последнем месте стоит и старый, испытанный
метод PHYSICAL_RAM * 2. На старых машинах он работает
лучше всего, хотя на современных, с большим количеством
RAM начал терять свою актуальность.
в целом, довольно сложно сказать, когда начнется
активный своппинг. Даже на машинах с 16MB RAM (и даже
меньше) с установленной NetBSD все работает достаточно
хорошо, пока не будет запущено
17.2.2. Системные сервисы
На серверах хорошая работа сервисов имеет принципиальное
значение. Увеличение быстродействия возможно не только
улучшением аппаратной части, но и своевременным обновлением
программного обеспечения, которое может работать быстрее.
Другим хорошим примером может служить старый вопрос:
«Использовать или нет inetd?». Рассмотрим
pop3. Вызов его через inetd быстро сможет исчерпать ресурсы
системы, что приведет к замедлению работы системы в целом.
Установка демона pop3, не связанного с inetd может помочь
решить ситуацию.
17.2.3. Ядро NetBSD
От ядра системы очень сильно зависит производительность
системы и хотя оптимизация ядра описана несколько ниже по
тексту, вкратце коснемся этой темы и здесь.
Оптимизация ядра NetBSD возможна в следующих направлениях:
удаление лишних драйверов
опции конфигурации
системные установки
17.2.3.1. Удаление лишних драйверов
Удаление лишних драйверов из состава ядра приносит
следущие результаты: быстрее происходит загрузка системы,
занимается меньше памяти, вследствии уменьшения размера
ядра, быстрее происходит отклик ядра.
17.2.3.2. Опции конфигурации
Опции конфигурации позволяют нам задействовать или
отключать некоторые подсистемы, специфичные аппаратные
средства и файловые системы. Отключение неиспользуемых
функций также может дать прирост производительности.
Самый простой пример – сервер FTP, на котором не запущено
ничего более. В этом случае нет необходимости в поддержке
ядром лишних файловых систем, типа NTFS. В случае же
наличия рабочей станции, возможно, такая необходимость
есть, для обеспечения совместного доступа к файлам.
17.2.3.3. Системные установки
System wide settings are controlled by the kernel,
a few examples are filesystem settings, network settings
and core kernel settings such as the maximum number of
processes. Almost all system settings can be at least
looked at or modified via the sysctl facility. Examples
using the sysctl facility are given later on.
17.3. Visual Monitoring Tools
NetBSD ships a variety of performance monitoring tools with
the system. Most of these tools are common on all UNIX systems.
In this section some example usage of the tools is given with
interpretation of the output.
17.3.1. Программа мониторинга процессов top
Эта программа выводит на экран список процессов с
ранжированием их по потребляемым ресурсам. Будучи запущеным
без параметров выглядит так:
Утилита показывает наиболее «прожорливое» приложение,
зависшие процессы или группы процессов, которые могут
вызывать проблемы. Приведенный выше пример – ненагруженая,
спокойная система. Ниже – совсем другой результат:
Кажется очевидным, какой процесс наиболее грузит систему,
но попробуем выяснить почему. bonnie – это утилита для
определения производительности диска и может записывать
файлы, варьируя пути и размеры. Так что, top указал нам на
самую ресурсопотребляющую программу, но не сказал почему
она так себя ведет.
17.3.1.1. Другие подобные программы
Изучая man команды top(1), можно узнать, что с
помощью этой команды можно менять приоритет и уничтожать
процессы, также можно установить дополнительные
фильтры.
17.3.2. Утилита sysstat
Man sysstat(1) указывает нам, что systat отображает
разнообразную системную статистику и основана на библиотеке
curses. Во время работы экран разделен на две части, верхнее
окно показывает текущее среднее число загрузки, в то время
как нижний экран зависит от директив пользователя.
В простейшем случае, эта утилита нам покажет загрузку
некоторого компонента системы, в этом примере, команда sysstat inet.tcp отобразит:
/0 /1 /2 /3 /4 /5 /6 /7 /8 /9 /10
Load Average |
0 connections initiated 19 total TCP packets sent
0 connections accepted 11 data
0 connections established 0 data (retransmit)
8 ack-only
0 connections dropped 0 window probes
0 in embryonic state 0 window updates
0 on retransmit timeout 0 urgent data only
0 by keepalive 0 control
0 by persist
29 total TCP packets received
11 potential rtt updates 17 in sequence
11 successful rtt updates 0 completely duplicate
9 delayed acks sent 0 with some duplicate data
0 retransmit timeouts 4 out of order
0 persist timeouts 0 duplicate acks
0 keepalive probes 11 acks
0 keepalive timeouts 0 window probes
0 window updates
Теперь более информативно. Счетчики накапливаются,
можно видеть много дополнительной информации. Теперь обратим
внимание на буферный кэш и просмотрим его с помощью systat
bufcache:
/0 /1 /2 /3 /4 /5 /6 /7 /8 /9 /10
Load Average
There are 1642 buffers using 6568 kBytes of memory.
File System Bufs used % kB in use % Bufsize kB % Util %
/ 877 53 6171 93 6516 99 94
/var/tmp 5 0 17 0 28 0 60
Total: 882 53 6188 94 6544 99
Ну что, снова довольно скучная система, но имеется в
наличии много информации. Раз у нас так все замечательно,
введем в систему ложную нагрузку, чтобы увидеть, как systat
можно использовать в качестве средства диагностики:
/0 /1 /2 /3 /4 /5 /6 /7 /8 /9 /10
Load Average |||
There are 1642 buffers using 6568 kBytes of memory.
File System Bufs used % kB in use % Bufsize kB % Util %
/ 811 49 6422 97 6444 98 99
Total: 811 49 6422 97 6444 98
Во первых, обратите внимание, что средняя нагрузка
возросла, но незначительно, в то время как как использование
файловой системы теперь составляет 99%. В реальной ситуации
поиска неисправностей, это помогло бы выявить поцесс,
делающий интенсивные операции ввода/вывода над файлом или
файловой системе.
17.4. Утилиты мониторинга
В дополнение к экранно-ориентированным утилитам мониторига
в NetBSD присутствуют текстовые утилиты. Эти утилиты присутствуют
во всех UNIX и UNIX-like системах.
17.4.1. fstat
Утилита fstat(1) сообщает о состоянии открытых
файлов в системе и многие администраторы используют ее для
контроля за созданием большого числа файлов или файлов
большого размера пользователями или процессами.
Вывод утилиты достаточно информативен, не требует
больших системных ресурсов и позволяет получить информацию
об используемом файле.
17.4.2. iostat
iostat(8) – утилита, имя которой соответстует
выполняемой задаче. Она сообщает о состоянии подсистем
ввода – вывода в системе. Когда эта утилита выполняется,
пользователь, с некоторой дискретностью, может наблюдать
примерно следующее:
Как и следовало ожидать, wd0 очень активен, загрузка
процессора повышается в некоторой зависимости от wd0. Малая
загрузка процессора свидетельствует о том, что сервер ftp
едва используется и это связано с усиленной работой bonnie++.
В данном случае с помощью одного инструмента сложно
локализовать проблему и необходимо проанализировать список
процессов, допустим с помощью утилиты systat bufcache.
17.4.3. ps
Используя ps(1) можно получить много информации
о состоянии системы. Чаще всего команда ps используется
для того, чтобы выделить какой-либо процесс по имени,
группе, владельцу и т.д. Вызванный без опций или параметров,
просто распечатывает информацию о пользователе, его
запустившем.
$ps
PID TT STAT TIME COMMAND
21560 p0 Is 0:00.04 -tcsh
21564 p0 I+ 0:00.37 ssh jrf.odpn.net
21598 p1 Ss 0:00.12 -tcsh
21673 p1 R+ 0:00.00 ps
21638 p2 Is+ 0:00.06 -tcsh
Не впечатляет… Поля довольно понятны, за исключением
STAT, в котором отображается статус процесса. I – простой,
S бездействует, R – runnable, + означает, что процесс
находится в приоритетном состоянии, и s означает, что
процесс – лидер сеанса. Это все очень просто, например
процесс 21560 – tcsh, простой процесс, следовательно tcsh
является и лидером.
В большинстве случаев эту утилиту используют для поиска
вполне определенных вещей. Для этого существуют дополнительные
опции, например -a видеть все процессы, -ax видеть все
процессы плюс не запущеные с терминала, -aux полная информация
о процессах:
#ps aux
USER PID %CPU %MEM VSZ RSS TT STAT STARTED TIME COMMAND
root 0 0.0 9.6 0 6260 ?? DLs 16Jul02 0:01.00 (swapper)
root 23362 0.0 0.8 144 488 ?? S 12:38PM 0:00.01 ftpd -l
root 23328 0.0 0.4 428 280 p1 S 12:34PM 0:00.04 -csh
jrf 23312 0.0 1.8 828 1132 p1 Is 12:32PM 0:00.06 -tcsh
root 23311 0.0 1.8 388 1156 ?? S 12:32PM 0:01.60 sshd: jrf@ttyp1
jrf 21951 0.0 1.7 244 1124 p0 S+ 4:22PM 0:02.90 ssh jrf.odpn.net
jrf 21947 0.0 1.7 828 1128 p0 Is 4:21PM 0:00.04 -tcsh
root 21946 0.0 1.8 388 1156 ?? S 4:21PM 0:04.94 sshd: jrf@ttyp0
nobody 5032 0.0 2.0 1616 1300 ?? I 19Jul02 0:00.02 /usr/pkg/sbin/httpd
...
Снова, большинство полей понятно, за исключением VSZ
и RSS. RSS – реальный размер процесса в 1024-байтовых
модулях, а SZ – виртуальный размер. Это все здорово, но
как ps может нам помочь? Хорошо, смотрите на эту измененную
версию того же самого вывода:
#ps aux
USER PID %CPU %MEM VSZ RSS TT STAT STARTED TIME COMMAND
root 0 0.0 9.6 0 6260 ?? DLs 16Jul02 0:01.00 (swapper)
root 23362 0.0 0.8 144 488 ?? S 12:38PM 0:00.01 ftpd -l
root 23328 0.0 0.4 428 280 p1 S 12:34PM 0:00.04 -csh
jrf 23312 0.0 1.8 828 1132 p1 Is 12:32PM 0:00.06 -tcsh
root 23311 0.0 1.8 388 1156 ?? S 12:32PM 0:01.60 sshd: jrf@ttyp1
jrf 21951 0.0 1.7 244 1124 p0 S+ 4:22PM 0:02.90 ssh jrf.odpn.net
jrf 21947 0.0 1.7 828 1128 p0 Is 4:21PM 0:00.04 -tcsh
root 21946 0.0 1.8 388 1156 ?? S 4:21PM 0:04.94 sshd: jrf@ttyp0
nobody 5032 9.0 2.0 1616 1300 ?? I 19Jul02 0:00.02 /usr/pkg/sbin/httpd
...
Учитывая, что мы считаем этот сервер слабо нагруженным,
PID 5032 сильно нагружает процессор. Анализируя вывод
команды ps, мы можем сделать вывод о процессах, которые
могут испытывать проблемы.
17.4.4. vmstat
Используя vmstat(1) можно получить информацию, касающуюся состояния виртуальной памяти. Мало чем отличаясь
от iostat, vmstat может быть вызван с указанием дискретности.
Следующее – некоторый типовой вывод, используя дискретность
5 и выводя 5 результатов:
Не очень много различий. Обратите внимание, так как
большинство работы производила система ввода/вывода,
фактически виртуальная память не очень расходовалась
вследствии использования для /tmp файловой системы mfs.
Это соотношение может быть нарушено:
Довольно страшно выглядит. Такой результат мы получили
используя bonny в системе, где /tmp использует файловую
систему mfs для хранения своих данных. Обратите внимание,
на то, что хоть и виртуальная память была очень нагружена,
процессор был свободен.
17.5. Сетевые утилиты
Иногда, проблемы возникают не в работе какой-то отдельно
взятой машины, а в сети – с кабельной разводкой или сетеыми
устройствами. То, как взаимодествуют другие машины в сети с
нашей NetBSD-машиной, может оказывать сильное влияние на
функционирование сервисов непосредственно на машине или
оказывать влияние на работу пользователей с этой машиной.
Реальный пример – когда в сети становится недступен DNS
сервер. Разрешение имени тогда идет долго и в конце концов
терпят неудачу, и тогда начинаютя обвинения в адрес NetBSD-машины,
раздаются крики пользователей что «сломался Интернет»
и т.д. Независимо от того, что произошло, NetBSD имеет
средства для поиска неисправности как на локальной машине,
так и в сети.
17.5.1. ping
Классическая утилита ping(8) показывает наличие
связи с удаленной машиной. В качестве параметра можно
указать IP адрес целевой машины или ее имя (если настроен
nsswitch.conf). Вот ее вывод:
#ping -c 3 marie
PING marie (172.16.14.12): 56 data bytes
64 bytes from 172.16.14.12: icmp_seq=0 ttl=255 time=0.571 ms
64 bytes from 172.16.14.12: icmp_seq=1 ttl=255 time=0.361 ms
64 bytes from 172.16.14.12: icmp_seq=2 ttl=255 time=0.371 ms
----marie PING Statistics----
3 packets transmitted, 3 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 0.361/0.434/0.571/0.118 ms
Этот вывод покажет нам, что не только есть связь, но
и количество прошедших пакетов, их размер, время прохождения
до удаленной машины. Также указывется соответствие IP
адреса к имени машины. Если не использовать сервер имен,
то можно воспользоваться только IP адресом.
#ping -c 1 172.16.20.5
PING ash (172.16.20.5): 56 data bytes
64 bytes from 172.16.20.5: icmp_seq=0 ttl=64 time=0.452 ms
----ash PING Statistics----
1 packets transmitted, 1 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 0.452/0.452/0.452/0.000 ms
Время доступа к машине весьма субьективный параметр.
Например для получения хорошего времени досупа мы можем
пинговать localhost:
#ping -c 4 localhost
PING localhost (127.0.0.1): 56 data bytes
64 bytes from 127.0.0.1: icmp_seq=0 ttl=255 time=0.091 ms
64 bytes from 127.0.0.1: icmp_seq=1 ttl=255 time=0.129 ms
64 bytes from 127.0.0.1: icmp_seq=2 ttl=255 time=0.120 ms
64 bytes from 127.0.0.1: icmp_seq=3 ttl=255 time=0.122 ms
----localhost PING Statistics----
4 packets transmitted, 4 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 0.091/0.115/0.129/0.017 ms
Это время намного меньше, потому что запрос никогда не
покидал машину. Утилита ping может использоваться для
определения состояния сети и измерения времени доступа к
различным хостам сети. Также она может быть использована
для некоторой локализации проблемы в сети – если есть три
машины под управлением NetBSD и с одной из них очень плохая
связь, можно предположить, что на ней что-либо неправильно
настроено.
17.5.2. traceroute
Утилита traceroute(8) служит для определения пути
пакета от одного хоста к другому. Например – путь пакета
между нашим ftp сервером и ftp. NetBSD.org:
#traceroute ftp.NetBSD.org
traceroute to ftp.NetBSD.org (204.152.184.75), 30 hops max, 40 byte packets
1 208.44.95.1 (208.44.95.1) 1.646 ms 1.492 ms 1.456 ms
2 63.144.65.170 (63.144.65.170) 7.318 ms 3.249 ms 3.854 ms
3 chcg01-edge18.il.inet.qwest.net (65.113.85.229) 35.982 ms 28.667 ms 21.971 ms
4 chcg01-core01.il.inet.qwest.net (205.171.20.1) 22.607 ms 26.242 ms 19.631 ms
5 snva01-core01.ca.inet.qwest.net (205.171.8.50) 78.586 ms 70.585 ms 84.779 ms
6 snva01-core03.ca.inet.qwest.net (205.171.14.122) 69.222 ms 85.739 ms 75.979 ms
7 paix01-brdr02.ca.inet.qwest.net (205.171.205.30) 83.882 ms 67.739 ms 69.937 ms
8 198.32.175.3 (198.32.175.3) 72.782 ms 67.687 ms 73.320 ms
9 so-1-0-0.orpa8.pf.isc.org (192.5.4.231) 78.007 ms 81.860 ms 77.069 ms
10 tun0.orrc5.pf.isc.org (192.5.4.165) 70.808 ms 75.151 ms 81.485 ms
11 ftp.NetBSD.org (204.152.184.75) 69.700 ms 69.528 ms 77.788 ms
В целом, не плохо. Пакет пошел с главного компьютера
на местный маршрутизатор, потом в сеть провайдера, затем
в Интернет и наконец к адресату. Показания traceroute также
являются субьективными, но повышенне время доступа на каком
либо участке сети может указать на проблему сетевого
оборудования. Утилита traceroute мало чем отличается от
утилиты ping по принципу действия. Теперь пример проблем
в сети:
#traceroute www.microsoft.com
traceroute: Warning: www.microsoft.com has multiple addresses; using 207.46.230.220
traceroute to www.microsoft.akadns.net (207.46.230.220), 30 hops max, 40 byte packets
1 208.44.95.1 (208.44.95.1) 2.517 ms 4.922 ms 5.987 ms
2 63.144.65.170 (63.144.65.170) 10.981 ms 3.374 ms 3.249 ms
3 chcg01-edge18.il.inet.qwest.net (65.113.85.229) 37.810 ms 37.505 ms 20.795 ms
4 chcg01-core03.il.inet.qwest.net (205.171.20.21) 36.987 ms 32.320 ms 22.430 ms
5 chcg01-brdr03.il.inet.qwest.net (205.171.20.142) 33.155 ms 32.859 ms 33.462 ms
6 205.171.1.162 (205.171.1.162) 39.265 ms 20.482 ms 26.084 ms
7 sl-bb24-chi-13-0.sprintlink.net (144.232.26.85) 26.681 ms 24.000 ms 28.975 ms
8 sl-bb21-sea-10-0.sprintlink.net (144.232.20.30) 65.329 ms 69.694 ms 76.704 ms
9 sl-bb21-tac-9-1.sprintlink.net (144.232.9.221) 65.659 ms 66.797 ms 74.408 ms
10 144.232.187.194 (144.232.187.194) 104.657 ms 89.958 ms 91.754 ms
11 207.46.154.1 (207.46.154.1) 89.197 ms 84.527 ms 81.629 ms
12 207.46.155.10 (207.46.155.10) 78.090 ms 91.550 ms 89.480 ms
13 * * *
.......
В данном случае сервер microsoft не может быть найден
или из-за большого числа переходов, или из-за блокирования
ICMP – пакетов межсетевым экраном, или из-за потерь пакетов
в канале. Если попробовать применить утилиту ping, то она
не будет работать, так что можно селать вывод о том, что
скорее всего заблокированы ICMP – пакеты на сеть
microsoft.
17.5.3. netstat
Другая проблема, которая мжет возникнуть, проблема
маршрутизации. Эти проблемы не всегда появляются вследствие
неправильной настройки. Команды route(8) and netstat(1) команды могут показать информацю о маршрутах
и сетевых подключениях соответственно.
Команда route может использоваться, чтобы смотреть и
изменять таблицы маршрутизации, в то время как netstat
может отобразит информацию о сетевых подключениях и маршрутах.
Вот вывод команды route:
#route show
Routing tables
Internet:
Destination Gateway Flags
default 208.44.95.1 UG
loopback 127.0.0.1 UG
localhost 127.0.0.1 UH
172.15.13.0 172.16.14.37 UG
172.16.0.0 link#2 U
172.16.14.8 0:80:d3:cc:2c:0 UH
172.16.14.10 link#2 UH
marie 0:10:83:f9:6f:2c UH
172.16.14.37 0:5:32:8f:d2:35 UH
172.16.16.15 link#2 UH
loghost 8:0:20:a7:f0:75 UH
artemus 8:0:20:a8:d:7e UH
ash 0:b0:d0:de:49:df UH
208.44.95.0 link#1 U
208.44.95.1 0:4:27:3:94:20 UH
208.44.95.2 0:5:32:8f:d2:34 UH
208.44.95.25 0:c0:4f:10:79:92 UH
Internet6:
Destination Gateway Flags
default localhost UG
default localhost UG
localhost localhost UH
::127.0.0.0 localhost UG
::224.0.0.0 localhost UG
::255.0.0.0 localhost UG
::ffff:0.0.0.0 localhost UG
2002:: localhost UG
2002:7f00:: localhost UG
2002:e000:: localhost UG
2002:ff00:: localhost UG
fe80:: localhost UG
fe80::%ex0 link#1 U
fe80::%ex1 link#2 U
fe80::%lo0 fe80::1%lo0 U
fec0:: localhost UG
ff01:: localhost U
ff02::%ex0 link#1 U
ff02::%ex1 link#2 U
ff02::%lo0 fe80::1%lo0 U
Значение флагов: U – действует, H – хост, G – шлюз.
О значении других флагов, читайте руководство man.
Теперь вывод netstat с параметрами r(маршруты) и n(не
использовать DNS):
Вышеупомянутый вывод является немного более подробным.
Так, как это может помочь? Хороший пример – когда при
подключении новой сети не прописывается маршрут к ней или
динамический маршрут загружается с ошибкой, в результате
появляется маршрут по умолчанию ведущий в никуда.
17.5.4. tcpdump
Последний по списку, но определенно не по значению, tcpdump(8), сетевой анализатор, с помощью которого
можно собрать очень много информации. Сейчас мы рассмотрим
вывод утилиты и объясненим некоторые из наиболее полезных
параметров tcpdump.
Учитывая, что сервер в этом примере выполняет почтовые
функции, из вывода, в принципе, все понятно. Утилита является
очень подробной, я предпочитаю первоначально выполнить
tcpdump без аргументов и послать текстовый вывод в файл
для более позднего изучения.
#tcpdump > tcpdump.out
tcpdump: listening on ex0
Так, что точно мы ищем? Это могут быть неправильные
пакеты, пакеты с определенного адреса или пределенного
типа, в общем, что угодно. С помощью tcpdump возможна
диагностика большого количества проблем в сети.
17.5.4.1. Использование tcpdump
Вот несколько примеров использования tcpdump:
Наличие двойных IP адресов:
tcpdump -e host ip-address
Для примера:
tcpdump -e host 192.168.0.2
Проблемы маршрутизации:
tcpdump icmp
Есть множество инструментальных средств сторонных
производителей, однако, NetBSD поставляется с хорошим
комплектом инструментальных средств для того, чтобы
разыскать проблемы сетевого уровня.
17.6. Аккаунтинг
NetBSD обладает широким набором средств анализа эффективности
для активного контроля, но что делать, если вести анализ
необходимо в течение долгого времени? Конечно, можно послать
вывод различных команд в файл и анализировать их позже с
помощью скриптов командной оболочки или каких либо других
программ. NetBSD по умолчанию предоставляет программисту,
администратору, или просто хоббитянину(у кого хобби такое)
достаточно мощный инструментарий для низкоуровнего
мониторинга.
17.6.1. Accounting
В то время как аккаунтинг используется на уровне
окружения пользователя, профилирование ядра с gprof
обеспечивает явное использование системного вызова.
Успользование утилит аккаунтинга может помочь при
анализе проблем производительности как сети, так и сервисов,
запущеных на машине.
Использование очень простое, необходимо выполнить с
правами пользователя root команду accton(8): accton filename
И вся информация будет добавляться в конец файла
filename. Команда lastcomm позволит просмотреть этот файл.
По умолчанию будет просмотрен файл /var/account/acct. Также может быть
указан любой другой файл.
Для остановки аккаунтинга достаточно ввести accton без
параметров.
17.6.2. Чтение информации аккаунтинга
Для чтения накопленной информации используются две
программы:
По умолчанию чтение производится из файла /var/account/acct,
но с помощью опции -f можно переопределить файл.
Очевидно, что использовать lastcomm в системе с
большим количеством пользователей достаточно тяжело. Тут
может помоч утилита sa.
17.6.2.2. sa
Утилита sa(расшифровывается как «печатать статистику
системного аккаунтинга») может использоваться для обработки
информации аккаунтинга. Также применяется для создания
интерактивных отчетов. Вот пример вывода этой команды:
Слева направо: полное время вызова, реальное время
в минутах, число пользователей, системное время в минутах,
среднее количество операций ввода/вывода, и имя
команды.
Команда sa может также использоваться для создания
файлов отчета или сообщений, основанных на шаблонах.
Например, вот – вывод процессов, отсортированных по
среднему использованию CPU:
Утилита sa весьма полезна на загруженных системах.
17.6.3. Как исполдьзовать аккаунтинг
Аккаунтинг, при его ведении и регулярном анализе, может
помочь предсказать появление проблем производительности,
после пары месяцев сбора статистики позволит понять, какие
изменения надо сделать, чтобы сохранить или повысить
производительность. Другой хороший пример – использование
сервера сети. Если нагрузка начинает увеличиваться, возможно
стоит предпринять некоторые действия, до того как она станет
реальной проблемой. Так что, вывод однозначный – как
здорово, что в NetBSD есть такие замечательные средства
контроля и все проблемы можно предсказать заранее!
17.7. Профили ядра
Профилирование ядра обычно используется для сравнения
работы системы на различных ядрах или для поиска проблем на
низком уровне. Регистрируются два различных параметра: частота
вызова функции и скорость выполнения каждой функции.
17.7.1. С чего начать
Для начала просмотрите разделы Раздел 17.9, «Оптимизация ядра»
и Глава 28, Компиляция ядра настоящего руководства.
Единственное различие в процедуре установки ядра с
профилированием заключается в необходимости добавить в
config опцию -p. Находясь в каталоге исходных текстов ядра ../compile/<KERNEL_NAME>.PROF,
в то время как GENERIC-ядро в ../compile/GENERIC.PROF.
Ниже следует краткая инструкция по тому, как скомпилировать
ядро с поддержкой профилирования для i386. Считаем, что
исходники доступны в /usr/src и
используется ядро GENERIC, что не всегда соответствует
действительности.
cd
/usr/src/sys/arch/i386/conf
config -p GENERIC
cd ../compile/GENERIC.PROF
make depend && make
cp /netbsd /netbsd.old
cp netbsd /
reboot
Как только новое ядро было установлено, и система
перезагрузилась, пришло время включать мониторинг и смотреть
на результаты.
17.7.1.1. Использование kgmon
Запускаем kgmon:
$kgmon -b
kgmon: kernel profiling is running.
Затем посылаем данные в файл gmon.out:
$kgmon -p
Делаем читаемый вывод:
$gprof /netbsd > gprof.out
В текущем каталоге gmon начинает искать файл gmon.out.
Выполняя только kgmon, вы не можете получить всей
информации, в которой вы нуждаетесь, однако, если Вы
можете получить данные для ядра GENERIC, для последующего
сравнения со своими ядрами.
17.7.2. Расшифровка вывода kgmon
Теперь, когда kgmon может собирать и анализировать
информацию, пришло время посмотреть на работу системы. В
нашем примере ядро GENERIC выполняется с профилированием
в течение приблизительно часа с только системными процессами,
дополнительной нагрузки нет, ошибок нет.
17.7.2.1. Flat Profile
В этом профиле представлен список функций, сколько
раз их вызывали и время их выполнения.
Как видно из результата вывода, имеется большое различие
в работе. Сначительно сократилось время простоя системы.
Основное различие состоит в том, что одна специфическая
функция имеет большое время работы с очень небольшим
количеством запросов. Эта функция – check_exec. Сначала
это может не показаться странным, но после выполнения
большого числа команд расхождение с Flat profile первого
измерения оказаться значительным:
Запрос в первом измерении сделан 37 раз и имеет большое
время работы. Очевидно, что работа этой функции неправильна.
Чтобы выявить другие функции, нам необходим график запросов,
вот – первая зависимость check_exec:
Обратите внимание, как время 8.69, кажется, затрагивает
две предыдущих функции. Возможно, что – то не так с ними,
однако, следующий образец check_exec доказывает иное:
Теперь мы можем видеть, что проблема, наиболее вероятно,
постоянно находится в check_exec.
Конечно, проблемы не всегда настолько просты и очевидны,
вот – простой код, который был вставлен в check_exec (функция находится в sys/kern/kern_exec.c):
...
/* A Cheap fault insertion */
for (x = 0; x < 100000000; x++) {
y = x;
}
..
Не очень красиво, но достаточно для показа работы
системы с профилированием.
17.7.4. Резюме:
Профилирование ядра позволяет искать и находить
неисправности в работе системы, поиск которых другими
средствами был бы затруднен. Это не очень тяжело и если вы
можете самостоятельно откомпилировать ядро, то вы можете
использовать систему с профилированием.
17.8. Оптимизация системы
Теперь, когда мы рассмотрели средства контроля и средства
анализа производительности, пришло время изучать методы
влияния на эту самую производительность. В этом разделе мы
рассмотрим средства, которые могут затронуть систему без
перекомпиляции ядра, в следующем разделе рассмотрим уже сборку
нового ядра.
17.8.1. Использование sysctl
Данная утилита используется для просмотра и установки
системных параметров. Так как параметров очень много,
рассмотреть здесь их все не представляется возможным. Но
приведем несколько примеров, например вывод переменной
PATH:
Довольно просто. Теперь кое-что, что фактически связано
с работой. Посмотрим параметр kern.maxfiles – он определяет
сколько одновременно может быть открыто файлов. На сильно
нагруженных системах, говорят, что могут появиться проблемы
из-за невозможности открыть файл.
$sysctl kern.maxfiles
kern.maxfiles = 1772
Отлично. Теперь изменим этот параметр. Мы должны владеть
правами пользователя root и использовать параметр -w:
Помните, что после перезагрузки изменения пропадут.
Есть два пути сохранения изменений – это внести изменения
в ядро и прекомпилировать его или внести изменения в файл
/etc/sysctl.conf:
kern.maxfiles=1972
17.8.2. memfs & softdeps
Работа операционной системы может быть улучшена изменением
сразу нескольких прараметров (также она может быть и
ухудшена). Этими параметрами является использование
файловых систем в памяти и/или soft updates.
17.8.2.1. Использование memfs
Когда использовать memfs, а когда нет – дело сугубо
субьективное. Использование на сервере с большим
количеством пользователей не рекомендуется. Однако на
персональной машине это выглядит довольно симпатично и
каталог obj и некоторые из tmp каталогов можно было бы
перенести в память. Смысл это имеет при соответствующем
размере памяти. С другой стороны, если система только
имеет 16 МБ оперативной памяти и /var/tmp
использует memfs, могут возникнуть большие проблемы с
приложениями, использующих /var/tmp.
В GENERIC – ядре memfs установлен по умолчанию. Чтобы
использовать memfs необходимо сначала определить раздел
файла подкачки. Быстрый взгляд на /etc/fstab
говорит, что им является /dev/wd0b.
Эта система – почтовый сервер, так что я хочу
использовать только /tmp с memfs.
Также на этой системе я связал /tmp
с /var/tmp для экономии дискового
пространства.
/dev/wd0b /var/tmp mfs rw 0 0
Удостоверьтесь, что каталоги пусты и никто не использует
их! Потом можно примонтировать этот раздел командой mount -a или перезагрузить систему.
17.8.2.2. Использование softdeps
Этот механизм позволяет не записывать мета-данные
немедленно на диск, что позволяет оптимизировать операции
ввода/вывода. soft updates не установлена по умолчанию
из-за особенностей лицензирования и потому, что эта
функция все еще считается экспериментальной. Да включения
этой функции обратитесь к главе Раздел 4.9, «Включение FFS soft-dependencies» руководства.
Однако, практика подтверждает, что работает это дело
хорошо. softdeps заставляет систему работать значительно
быстрее, например rm -f в обычном случае требует некоторое
время на выполнение, с softdeps все происходит практически
мгновенно. Много подробной информации о возможностях
softdep может быть найдено на странице
автора.
17.9. Оптимизация ядра
В то время, как многие параметры могут быть выставлены
с использованием sysctl, имеется очень много переменных
используемых для расширенного управления программным обеспечением
(например перенос сервисов из inetd), которые таким образом
настроить нельзя. В этом случае приходится использовать
перекомпиляцию ядра.
Конфигурирование ядра в NetBSD довольно непростое
занятие. Связано это с много численными зависимостями в
пределах файла конфигурации, единственный плюс – для
конфигурирования можно обойтись выводом dmesg и ascii
редактором. Ядро находится в src/sys/arch/ARCH/conf, где ARCH -
ваша архитектура. (например, на sparc это было бы под src/sys/arch/sparc/conf).
Конфигурирование ядра заключается в создании копии
файла конфигурации ядра и удаления(комментирования) всего
лишнего. Сейчас именно тот случай, когда dmesg(8)
становится вашим другом. dmesg(8) покажет все устройства,
обнаруженным ядром во время загрузки. Используя вывод dmesg(8) могут быть определены опции имеющихся устройств.
Для автоматизации действий может быть использован пакет
«adjustkernel».
17.9.2.1. Пример конфигурации
В данном примере мы конфигурируем ядро для ftp сервера,
убирая все лишние драйвера и сервисы – все, что может
замедлить работу. Копируем файл /usr/src/sys/arch/i386/conf/GENERIC
в файл FTP и приступаем к его редактированию.
В начале файла есть набор опций, включая maxuser,
которые мы оставим в покое, однако на много пользовательских
системах этот параметр можно и поправить. Далее идет тип
процессора. Руководствуясь выводом dmesg определяем:
Нам требуется только опция I686_CPU. В следущей секции
тоже все оставляем в покое за исключением PIC_DELAY – ее
рекомендуется выставить, если это не старая машина (не
ниже 686).
Дальше вниз до самых compat опций изменять ничего не
надо. Так как эта машина выполняет только функции сервера
FTP, все compat опции были выключены.
Следущая секция содержит в себе строки поддержки
файловых систем.
# File systems
file-system FFS # UFS
file-system LFS # log-structured file system
file-system MFS # memory file system
file-system CD9660 # ISO 9660 + Rock Ridge file system
file-system FDESC # /dev/fd
file-system KERNFS # /kern
file-system NULLFS # loopback file system
file-system PROCFS # /proc
file-system UMAPFS # NULLFS + uid and gid remapping
...
options SOFTDEP # FFS soft updates support.
...
Сетевые опции:
options INET # IP + ICMP + TCP + UDP
options INET6 # IPV6
options IPFILTER_LOG # ipmon(8) log support
Опцию IPFILTER_LOG мы оставим, та как планируем
использовать ipf.
Следующий раздел – подробные отладочные сообщения
для различных подсистем, так как эта машина уже работала
и не имела никаких проблем, все они прокомментированы.
17.9.2.2. Драйверы устройств
Элементы конфигурации указанные выше – дело простое
и обьяснимое. Драйверы устройство – совсем наоборот.
Вот маленький пример с CD-ROM.
...
cd0 at atapibus0 drive 0: <CD-540E, , 1.0A> type 5 cdrom removable
cd0: 32-bit data port
cd0: drive supports PIO mode 4, DMA mode 2, Ultra-DMA mode 2
pciide0: secondary channel interrupting at irq 15
cd0(pciide0:1:0): using PIO mode 4, Ultra-DMA mode 2 (using DMA data transfer
...
Теперь пришло время разыскивать этот раздел в файле
конфигурации. Обратите внимание, что CD находится на
atapibus и требует поддержки pciide. Раздел, который
представляет интерес в этом случае – раздел «IDE and
related devices». Также рядом лежат разделы ISA, PCMCIA
и т.д. На этой машине нет PCMCIA устройств, поэтому всю
секцию комментируем.
Всекции IDE ищем строку:
...
wd* at atabus? drive ? flags 0x0000
...
atapibus* at atapi?
...
Хорошо, довольно очевидно, что те строки должны быть
сохранены. Затем:
...
# ATAPI devices
# flags have the same meaning as for IDE drives.
cd* at atapibus? drive ? flags 0x0000 # ATAPI CD-ROM drives
sd* at atapibus? drive ? flags 0x0000 # ATAPI disk drives
st* at atapibus? drive ? flags 0x0000 # ATAPI tape drives
uk* at atapibus? drive ? flags 0x0000 # ATAPI unknown
...
Единственный тип устройства, который был в выводе dmesg(8) – это CD, остальное может быть
закомментировано.
Следующий пример чуть сложнее – сетевые интерфейсы.
В этой машине их два.
...
ex0 at pci0 dev 17 function 0: 3Com 3c905B-TX 10/100 Ethernet (rev. 0x64)
ex0: interrupting at irq 10
ex0: MAC address 00:50:04:83:ff:b7
UI 0x001018 model 0x0012 rev 0 at ex0 phy 24 not configured
ex1 at pci0 dev 19 function 0: 3Com 3c905B-TX 10/100 Ethernet (rev. 0x30)
ex1: interrupting at irq 11
ex1: MAC address 00:50:da:63:91:2e
exphy0 at ex1 phy 24: 3Com internal media interface
exphy0: 10baseT, 10baseT-FDX, 100baseTX, 100baseTX-FDX, auto
...
На первый взгляд может показаться, что у нас три
сетевые карты, но присмотревшись повнимательнее, мы
обнаружим:
exphy0 at ex1 phy 24: 3Com internal media interface
Мы имеем только две сетевые карты, поэтому, как и в
случае с CDROM, просто удаляем все, что мы не увидели в
выводе dmesg. Переходим в начало секции сетевых
интерфейсов:
...
# Network Interfaces
# PCI network interfaces
an* at pci? dev ? function ? # Aironet PC4500/PC4800 (802.11)
bge* at pci? dev ? function ? # Broadcom 570x gigabit Ethernet
en* at pci? dev ? function ? # ENI/Adaptec ATM
ep* at pci? dev ? function ? # 3Com 3c59x
epic* at pci? dev ? function ? # SMC EPIC/100 Ethernet
esh* at pci? dev ? function ? # Essential HIPPI card
ex* at pci? dev ? function ? # 3Com 90x[BC]
...
У нас есть устройство ex. Все остальное в разделе
PCI может быть заккоментировано, кроме строки:
exphy* at mii? phy ? # 3Com internal PHYs
Которая может быть как закомментирована, так и
сохранена.
17.9.2.3. Multi Pass
Когда я настраиваю ядро, я люблю сделать это дистанционно
в сеансе X, в одном окне вывод dmesg, в другом файл
конфигурации. Может иногда потребоваться выполнить
несколько проходов, чтобы восстановить черезчур урезанное
ядро, так как легко случайно удалить зависимости.
17.9.3. Building the New Kernel
Теперь пришло время компилировать и устанавливать ядро.
В каталоге conf нашего ftp сервера выполним следующую
команду:
$config FTP
Когда на экране появится предупреждение не забыть
сделать make depend:
$cd ../compile/FTP$make depend && make
Когда это сделано, сохраняем старое ядро и ставим
новое:
#cp /netbsd /netbsd.orig#cp netbsd /
Теперь перезагрузка. Если ядро не загружается, то
остановите процесс загрузки и введите boot
netbsd.orig для загрузки предыдущего ядра.
В этой главе описываются механизм и принципы работы библиотек Подключаемых Аутентификационных Модулей (PAM), будет показано как сконфигурировать PAM, внедрить его в приложение и написать модуль PAM.
16.2. Introduction
Библиотеки Pluggable Authentication Modules (PAM)являются обьединенным API для сервисов, требующих аутентификацию и позволяет системным администраторам добавлять новые методы аутентификации просто инсталировав новый модуль PAM и модифицировав правила аутентификации в файле конфигурации.
Впервые PAM был описан и разработан в 1995 Vipin Samar и Charlie Lai из Sun Microsystems и с тех пор не сильно изменился. В 1997 году Open Group опубликовала предварительную спецификацию X/Open Single Sign-on (XSSO), которая стандартизировала PAM API и добавляла расширения для единственной (или, скорее, интегрированной) подписи. В то время, когда писалась эта глава, стандарт еще не был утвержден.
Хотя эта глава больше применима к FreeBSD 5.x и NetBSD 3.x, которые используют OpenPAM, она может использоваться и при работе с FreeBSD 4.x, которая использует Linux-PAM и другими ОС, такими как Linux и Solaris™.
16.3. Термины и соглашения
16.3.1. Определения
Терминология в PAM довольно запутанная. Ни Neither Samar и Lai’s ни спецификация XSSO не делали попыток первоначального определения терминов и обьектов, входящих в PAM, поэтому с течением времени возникла неоднозначность и путанница. Первая попытка установления непротиворечивой и однозначной терминологии была предпринята в подробном докладе, написанным Эндрю Г. Морган (автор Linux-PAM) в 1999 году. Хотя это и был огромный шаг вперед, по мнению самого Моргана, терминология еще далека от совершенства. Поэтому начнем мы с точного определения всех акторов и обьектов, включенных в PAM.
аккаунт
Привилегии, которые претендент запрашивает у арбитра.
претендент
Пользователь или обьект, запрашивающий аутентификацию.
арбитр
Пользователь или обьект, который имеет право проверить полномочия претендента и предоставить или запретить предоставление привелегии.
цепочка
Последовательность модулей, которые будут вызваны в ответ на запрос PAM. Цепочка включает информацию о порядке вызова модулей, передаваемых параметрах, и методе интерпретации результатов.
клиент
Приложение, ответственное за инициализацию запроса на аутентификацию и готовое получить от него необходимую аутентификационную информацию.
средство
Одно из четырех основных групп функциональных возможностей, обеспечиваемых PAM: идентификация, управление аккаунтами, управление сеансами и обновление ключей аутентификации.
модуль
Набор из одной или более связанных функций, осуществляющих уникальный метод аутентификации, собранный в один (обычно, динамически загружаемый) бинарный файл и идентифицируемый уникальным именем.
политика
Законченный набор инструкций, описывающих как PAM обрабатывает запросы на обслуживание. Политика обычно состоит из четырех цепочек, по одной на каждое средство, хотя некоторые сервисы не используют все четыре средства.
сервер
Приложение, действующее от имени арбитра, для общения с клиентом, получения аутентификационной информации, проверки полномочий претендента и предоставления доступа.
служба
Класс серверов, обеспечивающих подобные или связанные функциональные возможности и требующий подобной аутентификации. Политики PAM определяются по одной на службу, так все серверы читают, что имя сервиса будет соответствовать имени политики.
сессия
Контекст, в пределах которого претенденту предоставляется обслуживание сервером. Одно из четырех средств PAM, а именно управление сеансом, занимается исключительно установкой и прерыванием этого контекста.
ключ
Некая информация, связанная с аккаунтом, такая как пароль или кодовая фраза, позволяющая претенденту идентифицировать себя.
транзакция
Последовательность запросов от того же самого претендента к тому же самому образцу того же самого сервера, начиная с аутентификации и установки сеанса и заканчивая прерыванием сеанса.
16.3.2. Примеры
В этом разделе мы проиллюстрируем значения некоторых терминов на простых примерах.
16.3.2.1. Одна программа в роли и клиента и сервера
В этом примере, пользователь alice использует su(1) для использования учетной записи root.
Процесс su(1) выступает в роли и клиента и сервера.
Ключом аутентификации будет xi3kiune.
Арбитром является root, поскольку у su(1) выставлен setuid root.
16.3.2.2. Разделенный клиент и сервер
В этом примере показано, как eve инициирует соединение ssh(1) с login.example.com, и логинится под именем bob. Боб должен был выбрать лучший пароль!
$whoami
eve
$ssh bob@login.example.com
bob@login.example.com's password: god
Last login: Thu Oct 11 09:52:57 2001 from 192.168.0.1
NetBSD 3.0 (LOGIN) #1: Thu Mar 10 18:22:36 WET 2005
Welcome to NetBSD!
$
Эта политика обращается к сервису sshd, (который может состоять не только из сервера sshd(8)).
auth, account, session и password будут средствами.
pam_nologin.so, pam_unix.so, pam_login_access.so, pam_lastlog.so и pam_permit.so являются модулями. Из этого примера ясно, что pam_unix.so предоставляет не менее двух средств (аутентификация и управление аккаунтом).
Есть несколько отличий между политиками PAM на FreeBSD и NetBSD:
По умолчанию, каждая конфигурация сделана для /etc/pam.d.
Если конфигурации не существует, то вы не получите доступа в систему, в отличие от FreeBSD, где имеется политика по умолчанию, принимающая аутентификацию.
Для аутентификации в NetBSD необходимо наличие не менее одного модуля required, requisite или binding.
16.4. Основное в PAM
16.4.1. Средства и примитивы
API PAM предлагает шесть различных примитивов аутентификации, сгруппированных в четырех средствах, которые описаны ниже.
auth
Аутентификация. Это средство занимается подтверждением претендента и установлением данных аккаунта. Оно предоставляет два примитива:
pam_authenticate(3) подтверждает подлинность претендента, обычно запрашивая ключ аутентификации и сравнивая это со значением, сохраненным в базе данных или полученный от сервера аутентификации.
pam_setcred(3) утанавливает данные аккаунта, такие как ID пользователя, членство в группах и лимит ресурсов.
account
Управление аккаунтом. Это средство проверяет доступность аккаунта, опираясь на такие данные, как время суток или загрузку сервера. Оно предоставляет единственный примитив:
Управление сессией. Это средство обрабатывает задачи, связанные с установкой и окончанием сеанса, типа учета входа в систему. Оно обеспечивает два примитива:
pam_open_session(3) исполняет задачи, связанные с установкой сеанса: добавляет запись в базах данных utmp и wtmp, запускает агента SSH и т.д.
pam_close_session(3) отвечает за разрыв сеанса: добавляет записи в базы данных utmp и wtmp, останавливает агента SSH и т.д.
password
Управление паролями. Это средство используется для смены аутентификационного ключа, связанного с аккаунтом, по запросу пользователя или по истечению срока действия. Предоставляется один примитив:
pam_chauthtok(3) изменяет ключ аутентификации, дополнительно проверяя его стойкость и не использовался ли он ранее.
16.4.2. Модули
Модули – это очень важная часть концепции PAM, в конце концов, они «M» в слове «PAM». Модуль PAM – самостоятельная программа, которая реализует примитивы в одном или более средствах для одного специфического механизма, например для базы паролей UNIX®, NIS, LDAP и Radius.
16.4.2.1. Именование модулей
FreeBSD и NetBSD реализуют каждый механизм в одном модуле, называемом pam_mechanism.so (для примера, pam_unix.so для механизма UNIX®). Другие реализации могут включать в себя отдельные модули для разных средств и содержать имя средства как имя механизма, например в Solaris™ имеется модуль pam_dial_auth.so.1, используемый для аутентификации dialup пользователей. Так же, почти каждый модуль имеет страницу руководства man, тем же именем, например pam_unix(8) описывает работу модуля pam_unix.so.
16.4.2.2. Нумерация версий модулей
Оригинальная реализация PAM в FreeBSD, базирующаяся на Linux-PAM не использовала номера версий для модулей. Обычно это вызывало проблемы с приложениями, которые были слинкованы с более старыми версиями системных библиотек, так как нет возможности загружать соответствующую версию, требуемую модулем.
OpenPAM, с другой стороны, ищет модули, которые имеют тот же самый номер версии как и библиотека PAM (в настоящее время 2 в FreeBSD и 0 в NetBSD) и загружает модуль , не соответствующий версии, только в случае, если нет подходящего модуля. Таким образом унаследованные модули могут быть обеспечены для унаследованных приложений, при этом обеспечивается работа приложений, завязанных на новые версии модулей.
Хотя модули PAM в Solaris™ и имеют номер версии, но он входит в имя модуля и должен быть включен в конфигурацию.
16.4.2.3. Путь к модулям
Нет общего каталога для чтобы хранить модули PAM. В FreeBSD, они расположены в /usr/lib, в NetBSD вы можете найти их в /usr/lib/security.
16.4.3. Цепочки и правила
Когда сервер инициирует транзакцию PAM, библиотека пытается загрузить правила для сервиса, указанного в вызове pam_start(3). Политика описывает метод обработки аутентификационного запроса и определяется в конфигурационном файле. Это и есть другая основная концепция PAM: администратор имеет возможность настраивать правила безопасности системы (в глобальном смысле), просто редактируя текстовый файл.
Политика состоит из четырех цепочек, по одной для каждого из четырех средств PAM. Каждая цепочка представляет собой последовательность инструкций конфигурации, определение модуля и некоторые (дополнительные) параметры доступа пройти к модулю, и флаги управления, которые описывают, как интерпретировать код возврата от модуля.
Понимание контрольных флагов является основным в понимании конфигурационных файлов PAM. Есть множество различных флагов:
binding
Если модуль был выполнен и небыло ошибок в предыдущих модулях, то цепочка немедленно заканчивается и принимается положительное решение о предоставлении доступа. Если модуль выдал ошибку, остальная часть цепочки выполнится, но запрос будет отклонен.
Этот флаг был введен Sun в Solaris™ 9 (SunOS™ 5.9)и поддерживается в OpenPAM.
required
Если модуль выполнен и выполнена остальная часть цепочки, то доступ предоставляется. Если модуль выдал ошибку, то цепочка продолжит выполняться, но запрос будет отклонен.
requisite
Если модуль выполнен и выполнена остальная часть цепочки, то доступ предоставляется. Если поизошла ошибка модуля, цепочка немедленно заканчивается, и запрос отклоняется.
sufficient
Если модуль выполняется нормально и никакой предыдущий модуль в цепочке не терпел неудачу, цепочка заканчивается и и принимается положительное решение о предоставлении доступа. В случае ошибки модуль игнорируется и выполняется остальная часть цепочки.
Поскольку семантика этого флага несколько запутанна, мы рекомендуем использовать binding, там где это возможно.
optional
Модуль будет выполнен, но его результат игнорируется. Если все модули в цепочке отмечены флагом optional, то доступ всегда будет предоставлен.
Когда сервер вызывает один из шести примитивов PAM, PAM отыскивает цепочку для средства, к которой примитив принадлежит и вызывает каждый из модулей, перечисленный в цепочке в порядке следования, пока не достигает конца, или не будет принято решение об окончании обработки (в случае выполнения с флагами binding или sufficient или ошибки с флагом requisite).
Обратите внимание, что возможно, хотя не очень обычно, перечислить модуль несколько раз в пределах одной цепочки. Например, модуль, который ищет имена пользователя и пароли на сервере каталогов, может быть вызван несколько раз с различными параметрами, определяющими различные серверы каталогов. PAM обрабатывает различные вызовы того же самого модуля в той же самой цепочке как и различные, несвязанные модули.
16.4.4. Транзакции
Жизненный цикл типичной транзакции PAM описан ниже. Обратите внимание, что в случае сбоя на любом шаге, сервер обязан доложить о возникшей ошибке клиенту и прервать транзакцию.
В случае необходимости, сервер получает привилегии арбитра через механизм, независимый от PAM— в общем случае он стартует как root или имеет setuid root.
Сервер вызывает pam_start(3) для инициализации библиотеки PAM, указания имени сервиса и аккаунта, регистрации и поддержания связи.
Сервер получает различную информацию, касающуюся транзакции (такую как имя претендента и имя хоста, на котором выполняется клиент) и посылает его PAM, используя pam_set_item(3).
Сервер вызывает pam_acct_mgmt(3) для проверки доступности и валидности запрашиваемого аккаунта. Если пароль корретен но устарел, man.pam.acct.mgmt.3; вернет PAM_NEW_AUTHTOK_REQD вместо PAM_SUCCESS.
Если предыдущий шаг вернул PAM_NEW_AUTHTOK_REQD, сервер вызовет pam_chauthtok(3) для смены клиентом ключа аутентификации аккаунта.
Теперь, когда претендент был должным образом заверен, сервер вызывает pam_setcred(3), чтобы установить полномочия требуемой учетной записи. Это возможно, потому что все действия осуществляются от имени арбитра и подтверждаются его полномочиями.
Как только полномочия будут утановлены, сервер вызовет pam_open_session(3) для открытия сессии.
Теперь сервер может предоставить клиенту сервис, например, запустить оболочку.
В заключение, сервер вызывает pam_end(3) для уведомления библиотеки PAM, что сессия закончена и используемые ресурсы могут быть освобождены.
16.5. Конфигурирование PAM
16.5.1. Файл политик PAM
16.5.1.1. Файл /etc/pam.conf
Традиционно, файл политик PAM называется /etc/pam.conf. Каждая строка этого файла один шаг в цепочке, как показано ниже:
login auth required pam_nologin.so no_warn
Поля, по порядку: имя сервиса, имя средства, контрольный флаг, имя модуля и аргументы модуля. Все дополнительные поля интерпретируются как аргументы модуля.
Отдельная цепочка создается для каждой пары сервис/средство. Для пары сервис/средство важен порядок следования строк, для отдельных сервисов или средств проядок следования не важен. Примеры в оригинальной документации сгруппированы по средствам и Solaris™ продолжает придерживаться этого в pam.conf, а FreeBSD группирует строки по сервисам. Оба эти подхода имеют место быть.
16.5.1.2. Каталог /etc/pam.d
OpenPAM и Linux-PAM поддерживают дополнительный механизм конфигурации, который является предпочтительным в FreeBSD и NetBSD. В этой схеме, каждая политика содержится в отдельном файле, именуемом по имени службы, к которому она обращается. Эти файлы находятся в /etc/pam.d/.
Файлы, содержащие по одной политике на сервер, имеют только четыре поля, вместо пяти у pam.conf: опускается имя сервиса. Таким образом, вместо строки в pam.conf мы получаем файл /etc/pam.d/login следующего содержания:
auth required pam_nologin.so no_warn
Как следствие этого упрощенного синтаксиса, появляется возможность использовать ту же самую политику для нескольких услуг, привязывая разные имена сервисов к одному файлу. Например, чтобы использовать одинаковую политику для su и sudo, можно сделать следующим образом:
#cd /etc/pam.d#ln -s su sudo
Эта конструкция будет работать, так как имя сервиса определяется не в файле конфигурации, а в его названии. Только поэтому один файл можно использовать для нескольких сервисов.
Так как политика кдля каждой службы сохраняется в отдельном файле, механизм pam.d позволяет сильно упростить установку политик для сторонних программых продуктов.
16.5.1.3. Порядок поиска политик
Как мы видели выше, политики PAM могут находиться в в множестве мест. Если для указанной службы не было найдено ни одного файла конфигурации, будет использоваться /etc/pam.d/other, в случае, если этот файл не существует, будет искаться соответствующая запись в файле /etc/pam.conf или использоваться сервис «other».
Главное, что необходимо понять, это то, что конфигурирование PAM основано на цепочках.
16.5.2. Разбор строки конфигурации
Как указывалось в главе Файл политик PAM, какдая строка файла конфигурации /etc/pam.conf состоит из четырех или более полей: имя службы, имя средства, контрольный флаг, имя модуля и необязательные аргументы модуля.
Имя сервиса обычно(но не всегда) означает имя вызываемого приложения. Если вы не уверены, то обратитесь к документации на приложение для определения используемого имени сервиса.
Обратите внимание, что если вы используете /etc/pam.d/ вместо /etc/pam.conf, имя сервиса определяется именем файла политики и не присутствует в файле конфигурации.
Аналогично, управляющий флаг – одно из четырех ключевых слов, описанных в разделе Цепочки и правила и указывает, как как интерпретировать код возврата от модуля. Linux-PAM поддерживает дополнительный синтаксис, который позволяет вам определить действие, связанное с кодом возврата, но этого стоит избегать, так как это не является стандартным поведением и пересекается с фукциями запросов вызовов сервисов (и очень отличается от пути Solaris™ и OpenPAM).
16.5.3. Политики
Для правильного конфигурирования PAM нужно понимание порядка интерпретации политик.
Когда приложение вызывает pam_start(3), библиотека PAM загружает политику для указанного сервиса и создает четыре цепочки модулей (по одной на каждое средство). Если одна или более этих цепочек пусты, то они заменяются соответствующими цепочками из политики для сервиса other.
Когда приложение вызывает один из шести примитивов PAM, библиотека PAM отыскивает цепочку для соответствующего средства и вызывает соответствующую сервисную функцию в каждом модуле, перечисленном в цепочке, в порядке перечисления в конфигурации. После каждого запроса используются тип модуля и код ошибки, возвращаемый сервисной функцией для определения дальнейших действий. За несколькими исключениями, применяется следующая схема:
Таблица 16.1. Выполнение цепочек PAM
PAM_SUCCESS
PAM_IGNORE
other
binding
if (!fail) break;
-
fail = true;
required
-
-
fail = true;
requisite
-
-
fail = true; break;
sufficient
if (!fail) break;
-
-
optional
-
-
-
Если в конце цепочки fail – истина, или когда выполняется «break», диспетчер возвращает код ошибки, выданный первым модулем, но котором произошел сбой. В противном случае, возвращается PAM_SUCCESS.
Первое исключение состоит в том, что ошибка PAM_NEW_AUTHTOK_REQD будет обработана как успешный вход, то есть в случае, если нет ошибок в модулях и не менее одного модуля вернули PAM_NEW_AUTHTOK_REQD, диспетчер возвратит PAM_NEW_AUTHTOK_REQD.
Второе исключение состоит в том, что pam_setcred(3) обрабатывает модули binding и sufficient как будто они required.
Третье и последнее исключение состоит в том, что pam_chauthtok(3) выполняет цепочку дважды (один раз предварительный и второй раз с новым паролем) и на предварительной стадии модули binding и sufficient обрабатываются, как будто они required.
Модуль pam_deny(8) является одним из самых простых доступных модулей, на любой запрос он отвечает PAM_AUTH_ERR. Это бывает полезно для быстрого отключения сервиса (добавьте в начало каждой цепочки) или для завершения цепочки sufficient модулей.
Модуль pam_echo(8) просто возвращает аргумент как сообщение PAM_TEXT_INFO. Этот модуль может быть полезен при отладке или вывода перед началом аутентификации сообщения «Unauthorized access will be prosecuted».
Модуль pam_exec(8) в качестве первого параметра принимает имя выполняемой программы, все последующие принимаются как аргументы запускаемой программы. Возможным применением может быть монтирование пользовательского каталога при его входе в систему.
Модуль pam_ftpusers(8) отработает правильно только в том случае, если пользователь перечислен в /etc/ftpusers. В настоящее время в NetBSD этот модуль не понимает расширенный синтаксис ftpd(8), но это будет исправлено в более поздных версиях.
Модуль pam_group(8) принимает или отклоняет претендента на основе членства его в определенной группе (обычно, wheel для su(1)). Это, в первую очередь, предназначено для сохранения традиционного стиля работы BSD su(1), но может применяться для ограничения доступа определенных групп пользователей к сервисам.
В NetBSD есть аргумент authenticate, с помощью которого пользователя просят подтвердить подлинность использования его собственного пароля.
Модуль pam_guest(8) позволяет входить в систему по заранее установленному гостевому имени. В качестве пароля могут быть введены любые данные, аутентификация проходит только имени. pam_guest(8) может применяться для предоставления анонимного доступа на FTP
Модуль pam_krb5(8) предоставляет функции идентификации пользователя с помощью Kerberos 5. У пользователя запрашивается пароль и получается новый Kerberos TGT. TGT проверяется, получая тикет для локального хоста. Полученные ключи сохраняются в кэше, соответствующим образом устанавливается переменная KRB5CCNAME. Кэш должен быть разрушен при выходе пользователя из системы kdestroy(1).
Модуль pam_ksu(8) обеспечивает только сервис аутентификации для Kerberos 5, чтобы определить, действительно ли претендент уполномочен получить привилегии аккаунта.
Модуль pam_login_access(8) обеспечивает выполнение примитива управления учетной записью, который предписывает ограничения входа в систему, указанные в таблице login.access(5).
Модуль pam_nologin(8) отклоняет не-root запросы на аутентификацию, в случае, если существует файл /var/run/nologin. Этот файл обычно создается shutdown(8) за пять минут до выключения системы.
Модуль pam_permit(8) — один из простейших доступных. На каждый запрос он возвращает PAM_SUCCESS. Этот модуль бывает полезен в качестве метки или для предотвращения появления пустой цепочки.
Модуль pam_rhosts(8) предоставляет только сервис аутентификации. Он выполняется без сообщения от ошибке если идентификатор целевого пользователя не 0 и удаленный хост и пользователь имеются в /etc/hosts.equiv или ~/.rhosts.
Модуль pam_rootok(8) сообщает об успехе, если и только если реальный пользовательский идентификатор процесса, вызывающий его – 0. Это полезно для несетевых услуг типа su(1) или passwd(1), к которым root должен иметь автоматический доступ.
Модуль pam_securetty(8) предоставляет только сервис учетной записи. Он применяется когда претендент запрашивает полномочия суперпользователя или процесс присоединяется к insecure TTY.
Модуль pam_self(8) сообщает об успехе если имена претендента и целевой учетной записи совпадают. Это наиболее полезно для несетевых услуг типа su(1), где тождество претендента может быть легко проверено.
Модуль pam_ssh(8) обеспечивает услуги и сеанса и идентификации. Сервис аутентификации позволяет пользователям, защитившим свои секретные ключи в каталоге ~/.ssh кодовыми фразами, ввести кодовую фразу для подтверждения своей подлинности. Сервис сеанса запускает ssh-agent(1) и производит предварительную загрузку ключей, которые расшифровываются в фазе аутентификации. Эта особенность особенно полезна для входа на консоль локальной машины или входа в X (используя xdm(1) or или другой понимающий PAM X менеджер).
Этот модуль осуществляет фундаментальнуюо схему аутентификации пароля. Необходимо принять все меры, по обеспечению работы модуля только по безопасному соединению, в противном случае, кодовая фраза SSH может быть скомпрометирована.
Рассмотрим еще один аспект использования pam_ssh(8). Пользователи часто предполагают, что установленные права доступа будут надежной защитой для ключей и указывают простую кодовую фразу или не указывают ее вовсе. Так как администратор системы не имеет никаких эффективных средств для контроля качества кодовых фраз, то есть риск компрометации системы.
Модуль pam_unix(8) реализует традиционную аутентификацию UNIX® по паролю, используя getpwnam(3) в FreeBSD или getpwnam_r(3) в NetBSD для получения доступа к целевой учетной записи для сравнения пароля учетной записи и пароля, введенного претендентом. Также, этот модуль предоставляет сервис управления учетной записью (смена пароля при истечении его срока действия) и сервис смены пароля. Это, вероятно, самый полезный модуль, так как большинство администраторов хотело бы придерживаться исторически сложившейся методики аутентификации.
Модуль pam_opie(8) реализует метод аутентификации opie(4). Система opie(4) построена на механизме вопрос-ответ, где ответ на каждый вопрос является прямой функцией от вопроса и кодовой фразы, так что ответ может быть легко вычислен «на лету» тем, кому известна кодовая фраза, при этом исчезает потребность в списках пользователей. Кроме того, opie(4) никогда не использует вопрос, на который был дан корректный ответ, что позволяет избежать уязвимости «replay attacks».
pam_opieaccess(8) — это модуль-компаньон к pam_opie(8). Его цель состоит в том, чтобы установить ограничения, описанные в opieaccess(5), которые регулируют условия, при которых пользователю, который обычно подтверждал подлинность себя, используя opie(4), разрешают использовать дополнительные методы. Это наиболее часто используется, чтобы запретить использование аутентификации по паролю от недоверенных хостов.
Для эффективной работы, модуль pam_opieaccess(8) должен быть указан как requisite сразу после записи sufficient для pam_opie(8), и перед любыми другими модулями в цепочке auth .
Модуль pam_passwdqc(8) просто проверяет стойкость пароля. В дополнение к проверке паролей на стойкость, этот модуль предлагает поддержку кодовых фраз и может обеспечить генерирование случайного пароля.
Модуль pam_skey(8) реализует метод аутентификации по одноразовым паролям (S/Key One Time Password (OTP)), используя базу данных /etc/skeykeys.
16.7. Программирование приложений PAM
Этот раздел еще не написан.
16.8. Программирование модулей PAM
Этот раздел еще не написан.
16.9. Пример приложения PAM
Ниже представлена простейшая реализация su(1) для использования PAM. Обратите внимание на то, что используется специфичная для OpenPAM функция сеанса связи openpam_ttyconv(3), прототипом которой является security/openpam.h. Если вы хотите реализовать это приложение на системе, использующей другую реализацию библиотек PAM, то должны использовать другую функцию сеанса связи. Стабильную функцию сеанса связи удивительно сложно реализовать, представленная в Простая функция сеанса связи PAM хороша для примера, но не должна использоваться в реальных приложениях.
#include <sys/param.h>
#include <sys/wait.h>
#include <err.h>
#include <pwd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <syslog.h>
#include <unistd.h>
#include <security/pam_appl.h>
#include <security/openpam.h> /* for openpam_ttyconv() */
extern char **environ;
static pam_handle_t *pamh;
static struct pam_conv pamc;
static void
usage(void)
{
fprintf(stderr, "Usage: su [login [args]]\n");
exit(1);
}
int
main(int argc, char *argv[])
{
char hostname[MAXHOSTNAMELEN];
const char *user, *tty;
char **args, **pam_envlist, **pam_env;
struct passwd *pwd;
int o, pam_err, status;
pid_t pid;
while ((o = getopt(argc, argv, "h")) != -1)
switch (o) {
case 'h':
default:
usage();
}
argc -= optind;
argv += optind;
if (argc > 0) {
user = *argv;
--argc;
++argv;
} else {
user = "root";
}
/* initialize PAM */
pamc.conv = &openpam_ttyconv;
pam_start("su", user, &pamc, &pamh);
/* set some items */
gethostname(hostname, sizeof(hostname));
if ((pam_err = pam_set_item(pamh, PAM_RHOST, hostname)) != PAM_SUCCESS)
goto pamerr;
user = getlogin();
if ((pam_err = pam_set_item(pamh, PAM_RUSER, user)) != PAM_SUCCESS)
goto pamerr;
tty = ttyname(STDERR_FILENO);
if ((pam_err = pam_set_item(pamh, PAM_TTY, tty)) != PAM_SUCCESS)
goto pamerr;
/* authenticate the applicant */
if ((pam_err = pam_authenticate(pamh, 0)) != PAM_SUCCESS)
goto pamerr;
if ((pam_err = pam_acct_mgmt(pamh, 0)) == PAM_NEW_AUTHTOK_REQD)
pam_err = pam_chauthtok(pamh, PAM_CHANGE_EXPIRED_AUTHTOK);
if (pam_err != PAM_SUCCESS)
goto pamerr;
/* establish the requested credentials */
if ((pam_err = pam_setcred(pamh, PAM_ESTABLISH_CRED)) != PAM_SUCCESS)
goto pamerr;
/* authentication succeeded; open a session */
if ((pam_err = pam_open_session(pamh, 0)) != PAM_SUCCESS)
goto pamerr;
/* get mapped user name; PAM may have changed it */
pam_err = pam_get_item(pamh, PAM_USER, (const void **)&user);
if (pam_err != PAM_SUCCESS || (pwd = getpwnam(user)) == NULL)
goto pamerr;
/* export PAM environment */
if ((pam_envlist = pam_getenvlist(pamh)) != NULL) {
for (pam_env = pam_envlist; *pam_env != NULL; ++pam_env) {
putenv(*pam_env);
free(*pam_env);
}
free(pam_envlist);
}
/* build argument list */
if ((args = calloc(argc + 2, sizeof *args)) == NULL) {
warn("calloc()");
goto err;
}
*args = pwd->pw_shell;
memcpy(args + 1, argv, argc * sizeof *args);
/* fork and exec */
switch ((pid = fork())) {
case -1:
warn("fork()");
goto err;
case 0:
/* child: give up privs and start a shell */
/* set uid and groups */
if (initgroups(pwd->pw_name, pwd->pw_gid) == -1) {
warn("initgroups()");
_exit(1);
}
if (setgid(pwd->pw_gid) == -1) {
warn("setgid()");
_exit(1);
}
if (setuid(pwd->pw_uid) == -1) {
warn("setuid()");
_exit(1);
}
execve(*args, args, environ);
warn("execve()");
_exit(1);
default:
/* parent: wait for child to exit */
waitpid(pid, &status, 0);
/* close the session and release PAM resources */
pam_err = pam_close_session(pamh, 0);
pam_end(pamh, pam_err);
exit(WEXITSTATUS(status));
}
pamerr:
fprintf(stderr, "Sorry\n");
err:
pam_end(pamh, pam_err);
exit(1);
}
16.10. Пример модуля PAM
Ниже представлена минимальная реализация pam_unix(8), предоставляющая только сервис аутентификации. Этот модуль должен работать со всеми реализациями PAM, но применяет расширения OpenPAM: обратите внимание на использование pam_get_authtok(3), который черезвычайно упрощает реализацию подсказки пользователю на ввод пароля..
#include <sys/param.h>
#include <pwd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <security/pam_modules.h>
#include <security/pam_appl.h>
#ifndef _OPENPAM
static char password_prompt[] = "Password:";
#endif
#ifndef PAM_EXTERN
#define PAM_EXTERN
#endif
PAM_EXTERN int
pam_sm_authenticate(pam_handle_t *pamh, int flags,
int argc, const char *argv[])
{
#ifndef _OPENPAM
struct pam_conv *conv;
struct pam_message msg;
const struct pam_message *msgp;
struct pam_response *resp;
#endif
struct passwd *pwd;
const char *user;
char *crypt_password, *password;
int pam_err, retry;
/* identify user */
if ((pam_err = pam_get_user(pamh, &user, NULL)) != PAM_SUCCESS)
return (pam_err);
if ((pwd = getpwnam(user)) == NULL)
return (PAM_USER_UNKNOWN);
/* get password */
#ifndef _OPENPAM
pam_err = pam_get_item(pamh, PAM_CONV, (const void **)&conv);
if (pam_err != PAM_SUCCESS)
return (PAM_SYSTEM_ERR);
msg.msg_style = PAM_PROMPT_ECHO_OFF;
msg.msg = password_prompt;
msgp = &msg;
#endif
for (retry = 0; retry < 3; ++retry) {
#ifdef _OPENPAM
pam_err = pam_get_authtok(pamh, PAM_AUTHTOK,
(const char **)&password, NULL);
#else
resp = NULL;
pam_err = (*conv->conv)(1, &msgp, &resp, conv->appdata_ptr);
if (resp != NULL) {
if (pam_err == PAM_SUCCESS)
password = resp->resp;
else
free(resp->resp);
free(resp);
}
#endif
if (pam_err == PAM_SUCCESS)
break;
}
if (pam_err == PAM_CONV_ERR)
return (pam_err);
if (pam_err != PAM_SUCCESS)
return (PAM_AUTH_ERR);
/* compare passwords */
if ((!pwd->pw_passwd[0] && (flags & PAM_DISALLOW_NULL_AUTHTOK)) ||
(crypt_password = crypt(password, pwd->pw_passwd)) == NULL ||
strcmp(crypt_password, pwd->pw_passwd) != 0)
pam_err = PAM_AUTH_ERR;
else
pam_err = PAM_SUCCESS;
#ifndef _OPENPAM
free(password);
#endif
return (pam_err);
}
PAM_EXTERN int
pam_sm_setcred(pam_handle_t *pamh, int flags,
int argc, const char *argv[])
{
return (PAM_SUCCESS);
}
PAM_EXTERN int
pam_sm_acct_mgmt(pam_handle_t *pamh, int flags,
int argc, const char *argv[])
{
return (PAM_SUCCESS);
}
PAM_EXTERN int
pam_sm_open_session(pam_handle_t *pamh, int flags,
int argc, const char *argv[])
{
return (PAM_SUCCESS);
}
PAM_EXTERN int
pam_sm_close_session(pam_handle_t *pamh, int flags,
int argc, const char *argv[])
{
return (PAM_SUCCESS);
}
PAM_EXTERN int
pam_sm_chauthtok(pam_handle_t *pamh, int flags,
int argc, const char *argv[])
{
return (PAM_SERVICE_ERR);
}
#ifdef PAM_MODULE_ENTRY
PAM_MODULE_ENTRY("pam_unix");
#endif
16.11. Простая функция сеанса связи PAM
Функция сеанса связи, представленная ниже – очень упрощенная версия openpam_ttyconv(3) из OpenPAM. Она полностью функциональна, и должна дать читателю хорошую базу относительно того, как функция сеанса связи должна себя вести, но она слишком проста для реального использования. Даже если вы не используете OpenPAM, не стесняйтесь изучать исходный текст и приспосабливать openpam_ttyconv(3) к вашим требованиям. Мы полагаем, что она будет столь же стабильна, как ориентированная на tty функция сеанса связи.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <security/pam_appl.h>
int
converse(int n, const struct pam_message **msg,
struct pam_response **resp, void *data)
{
struct pam_response *aresp;
char buf[PAM_MAX_RESP_SIZE];
int i;
data = data;
if (n <= 0 || n > PAM_MAX_NUM_MSG)
return (PAM_CONV_ERR);
if ((aresp = calloc(n, sizeof *aresp)) == NULL)
return (PAM_BUF_ERR);
for (i = 0; i < n; ++i) {
aresp[i].resp_retcode = 0;
aresp[i].resp = NULL;
switch (msg[i]->msg_style) {
case PAM_PROMPT_ECHO_OFF:
aresp[i].resp = strdup(getpass(msg[i]->msg));
if (aresp[i].resp == NULL)
goto fail;
break;
case PAM_PROMPT_ECHO_ON:
fputs(msg[i]->msg, stderr);
if (fgets(buf, sizeof buf, stdin) == NULL)
goto fail;
aresp[i].resp = strdup(buf);
if (aresp[i].resp == NULL)
goto fail;
break;
case PAM_ERROR_MSG:
fputs(msg[i]->msg, stderr);
if (strlen(msg[i]->msg) > 0 &&
msg[i]->msg[strlen(msg[i]->msg) - 1] != '\n')
fputc('\n', stderr);
break;
case PAM_TEXT_INFO:
fputs(msg[i]->msg, stdout);
if (strlen(msg[i]->msg) > 0 &&
msg[i]->msg[strlen(msg[i]->msg) - 1] != '\n')
fputc('\n', stdout);
break;
default:
goto fail;
}
}
*resp = aresp;
return (PAM_SUCCESS);
fail:
for (i = 0; i < n; ++i) {
if (aresp[i].resp != NULL) {
memset(aresp[i].resp, 0, strlen(aresp[i].resp));
free(aresp[i].resp);
}
}
memset(aresp, 0, n * sizeof *aresp);
*resp = NULL;
return (PAM_CONV_ERR);
}
NetBSD использует подсистему CMU RAIDframe. RAIDframe впервые появился именно в NetBSD и впоследствии был перенесен в OpenBSD и FreeBSD. NetBSD в составе ядра имеет еще несколько RAID систем называемых Vinum и Глава 14, Конфигурация Concatenated Disk Device (CCD), которые здесь не рассматриваются. Возможно. вам стоит посмотреть начальную информацию для получения начальных знаний о терминологии и концепции RAID. Как минимум вы должны быть знакомы с уровнями RAID. RAID – Adaptec предоставляет превосходное руководство, некоторый обьем информации содержится в raid(4)
15.1.2. Предупреждение о целостности данных, резервных копиях и высокой доступности
Во-первых, потому что RAIDframe является программной реализацией RAID, в отличие от аппаратной реализации, нуждающейся в специальном контроллере, системные администраторы должны обратить пристальное внимание к работе «критических» приложений. Для таких проектов стоит рассмотреть возможность использования поддерживаемых NetBSD RAID устройств. В этом случае вы самостоятельно принимаетет решение о выборе модели, но я рекомендую вам обратить внимание на такие факторы как управляемость, поддержка производителем, балансировка нагрузки и отказоустойчивость.
Во-вторых, в зависимости от используемого уровня RAID, RAIDframe обеспечивает некоторую избыточность в случае аппаратного сбоя. Однако это не является заменой резервному копированию! Программные и пользовательские ошибки все еще могут привести к потере данных. RAIDframe может использоваться как механизм облегчающий резервное копирование при отсутствии соответствующих аппаратных средств. И наконец, «высокая доступность» RAID является только малым компонентом обеспечения доступности данных в целом.
Дадим хороший совет: Резервируйте ваши данные!
15.1.3. Получение помощи
Если вы столкнулись с проблемами при использовании RAIDframe, то у вас есть несколько путей получения помощи.
Поиск в архивах списков рассылки. К сожалению, нет списка рассылки NetBSD, непосредственно посвященному RAIDframe. В связи с этим, разные темы могут начинаться и заканчиваться в разных списках. Как минимум, просмотрите netbsd-help@NetBSD.org, netbsd-users@NetBSD.org, current-users@NetBSD.org. Также стоит обратить на список рассылки используемой платформы: port-${ARCH}@NetBSD.org.
Предостережение
Поскольку RAIDframe постоянно развивается, имеющаяся в списках рассылки информация может быть уже неактуальной и неверной.
Если в не смогли решить проблему, то сделайте следующее: пошлите сообщение в список рассылки, содержащее наиболее полное описание проблемы, сопроводив его всей доступной вам отладочной информацией и сообщениями об ошибках, включая выводом dmesg(8) из файла /var/run/dmesg.boot, файл конфигурации ядра config(8), /etc/raid[0-9].conf, /var/log/messages или stdout/stderrraidctl(8). Также включите описание предпринятых вами шагов для решения проблемы. Будьте терпеливы в ожидании ответа.
15.2. Установка поддержки RAIDframe
Для использования RAID требуется внесение изменений в программную и аппаратную конфигурацию.
15.2.1. Поддержка в ядре
Мы должны удостовериться, что имеется поддержка RAID в текущем ядре, в ядре GENERIC необходимые опции уже включены. Если вы используете собственное ядро, то удостоверьтесь, что оно содержит следущие опции:
pseudo-device raid 8 # RAIDframe disk driver
options RAID_AUTOCONFIG # auto-configuration of RAID components
Поддержка RAID должна быть обнаружена ядром NetBSD, что может быть проверено с помощью команды dmesg(8).
Ядро также должно содержать статическую привязку адресов шины и устройств в /dev. Это позволит гарантировать правильное размещение дисков в RAID в случае сбоя после перезагрузки. Обратитесь к главе Глава 28, Компиляция ядра для настройки, сборки и установки нового ядра.
В случае SCSI привязка будет выглядеть примерно таким образом:
sd0 at scsibus0 target 0 lun ? # SCSI disk drives
sd1 at scsibus0 target 1 lun ? # SCSI disk drives
sd2 at scsibus0 target 2 lun ? # SCSI disk drives
sd3 at scsibus0 target 3 lun ? # SCSI disk drives
sd4 at scsibus0 target 4 lun ? # SCSI disk drives
sd5 at scsibus0 target 5 lun ? # SCSI disk drives
sd6 at scsibus0 target 6 lun ? # SCSI disk drives
Или для дисков EIDE/ATA:
wd0 at atabus0 drive 0 flags 0x0000
wd1 at atabus0 drive 1 flags 0x0000
wd2 at atabus1 drive 0 flags 0x0000
wd3 at atabus1 drive 1 flags 0x0000
Как только вы закончите этот процесс, возможно вас заинтересует распределение дисков относительно controller/bus/ID. Для системы, содержащей более чем два диска можно составить некоторый порядок действий, особенно важный для i386:
Таблица 15.1. Пример аппаратной конфигурации для i386
Component
BIOS Mapping
Boot Block Device
Kernel Device
Disk0
0×80
hd0
wd0 at atabus0 drive 0 flags 0×0000
Disk1
0×81
hd1
wd1 at atabus0 drive 1 flags 0×0000
15.2.2. Избыточность питания и кэширование дисков:
Если ваша система располагает источником бесперебойного питания (UPS) и/или несколькими блоками питания, то вам стоит рассмотреть вопрос включения кэша на чтение/запись. На системах без резервирования питания есть риск потери данных, находящихся в кэше, в случае пропадания электроэнергии.
Для SCSI дисков вы можете использовать утилиту scsictl(8):
#scsictl /dev/rsd0{c,d} getcache
/dev/rsd0d: no caches enabled
/dev/rsd0d: caching parameters are savable
#scsictl /dev/rsd0{c,d} setcache rw save #scsictl /dev/rsd0{c,d} getcache
/dev/rsd0d: read cache enabled
/dev/rsd0d: write-back cache enabled
/dev/rsd0d: caching parameters are savable
Для дисков на других шинах (EIDE, SATA, USB, IEEE1394) можно использовать atactl(8) или пользоваться виртуальной шиной SCSI.
15.3. Пример: реализация RAID-1
В этом примере рассказывается про установку RAID-1. В случае RAID-1 компоненты зеркалируются и сервер сохранит функциональность при выходе из строя одного из дисков. Целью примера и будет обеспечение необходимого уровня избыточности для:
Нормального выполнения операций до появления технологического окна.
В том маловероятном случае, когда отказ вызовет перезагрузку системы, система будет способно быстро реконфигурироваться для загрузки с оставшегося компонента (зависит от платформы).
Рисунок 15.1. Размещение логических дисков в RAID-1
Поскольку RAID-1 обеспечивает и избыточность и повышение производительности, самым разумным будет его использование для критических «системных» разделов, таких как /, /usr, /var, swap, где операции чтения чаще, чем операции записи. Для других файловых систем, таких как /home или /var/{application} стоит рассмотреть другой уровень RAID. В случае простого создания тома RAID-1 для не корневого раздела можно воспользоваться готовым примером из страницы руководства man, но поскольку корневой раздел должен быть загрузочным, нам придется предпринять некоторые шаги в ходе начальной установки.
Замечание
В этом примере будет совсем немного отличий при работе на платформах i386 и sparc64 в процессе уменьшения черезмерного дублирования. Эти моменты являются косметическими и будут указываться особо. В случае серьезных отличий порядок действий для разных платформ будет описан отдельно.
15.3.1. Схема псевдо-процессов
Хотя довольно много наработок было сделано в специализированных копиях NetBSD для специфичных мобильных носителей, инструментарий и поддержка RAIDframe находится на недостаточно высоком уровне. Вследствие этого, нижеследующий псевдо-процесс является стандартом де-факто при установке RAID-1.
Установка заготовки NetBSD на Disk0.
Рисунок 15.2. Подготовка к первичной установке на Disk0/wd0
Используйте установленную на Disk0/wd0 систему для создания RAID состоящего из одного Disk1/wd1.
Рисунок 15.3. Setup RAID Set
Перезагрузите систему после создания на Disk1/wd1 тома RAID.
Рисунок 15.4. Reboot using Disk1/wd1 of RAID
Add / re-sync Disk0/wd0 back into the RAID set.
Рисунок 15.5. Зеркалируйте Disk1/wd1 на Disk0/wd0
15.3.2. Обзор аппаратного обеспечения
В настоящее время NetBSD для платформ i386 sparc64 поддерживается загрузка только с RAID-1. Загрузка с RAID осуществляется на первом этапе работы загрузчика и заключается в определении 4.2BSD/FFS и RAID разделов. Код первого загрузочного кода должен только получить данные о файловых системах и разделах, чтобы передать их второму этапу загрузки. Поэтому, в любое время, BIOS или другое программное обеспечение низкого уровня должно быть способно прочитать и выполнить первый блок начального загрузчика. На платфирме i386 это реализуется производителем дискового контроллера, на sparc64 за это отвечает IEEE 1275 Sun OpenBoot Firmware.
В этой статье рассматриваются два идентичных диска IDE (/dev/wd{0,1}), которые и будут зеркалированы RAID-1). Эти диски идентифицируются как:
#grep ^wd /var/run/dmesg.boot
wd0 at atabus0 drive 0: <WDC WD100BB-75CLB0>
wd0: drive supports 16-sector PIO transfers, LBA addressing
wd0: 9541 MB, 19386 cyl, 16 head, 63 sec, 512 bytes/sect x 19541088 sectors
wd0: drive supports PIO mode 4, DMA mode 2, Ultra-DMA mode 5 (Ultra/100)
wd0(piixide0:0:0): using PIO mode 4, Ultra-DMA mode 2 (Ultra/33) (using DMA data transfers)
wd1 at atabus1 drive 0: <WDC WD100BB-75CLB0>
wd1: drive supports 16-sector PIO transfers, LBA addressing
wd1: 9541 MB, 19386 cyl, 16 head, 63 sec, 512 bytes/sect x 19541088 sectors
wd1: drive supports PIO mode 4, DMA mode 2, Ultra-DMA mode 5 (Ultra/100)
wd1(piixide0:1:0): using PIO mode 4, Ultra-DMA mode 2 (Ultra/33) (using DMA data transfers)
Замечание
Если вы используете SCSI, замените /dev/{,r}wd{0,1} на /dev/{,r}sd{0,1}
В этом примере оба наших диска выставлены как Master на разных каналах. Иметь два Master диска на одном канале врядли получится. В идеальном случае стоило бы иметь диски на отдельных каналах разных контроллеров. Некоторые SCSI контроллеры имеют несколько каналов на том же самом контроллере, однако шинный сброс SCSI на одном канале мог бы неблагоприятно затронуть другой канал, в случае перегрузки ASIC/IC.
Замечание
RAIDframe требует одинаковый размер компонентов. Если имеются различные компоненты, то общий размер определится по меньшему. В этом примере мы будем использовать диски одинаковых конфигураций. Также, рассмотрите вопрос наличия дисков на случай отказа оборудования.
Подсказка
Даже два диска одного производителя могут иметь различную геометрию вследствие «дефектов производства». Используйте низкоуровневое программное обеспечение для составления таблицы дефектов дисков. После этого уже можно определить кандидатов в RAID.
15.3.3. Начальная установка на Disk0/wd0
Установите систему на ваш диск Disk0/wd0, руководствуясь инструкциями в файле INSTALL для вашей платформы. Устанавливайте все наборы, но не беспокойтесь о настройке, так как это все равно будет перезаписано.
Подсказка
На платформе i386 при вопросе программы установки sysinst «use the entire disk for NetBSD» ответьте «yes».
Как только вы установили NetBSD на Disk0/wd0, можно начинать самое интересное. Disk1/wd1 должен быть виден и неиспользуем системой. Для распределения набора RAID-1 на диск Disk1/wd1 мы будем использовать disklabel(8).
Подсказка
Лучший способ гарантировать, что Disk1/wd1 является полностью пустым, состоит в том, чтобы ‘обнулить’ первые сектора диска с помощью dd(1). Это сотрет MBR (i386) или метку диска Sun (sparc64), так же как м метку диска NetBSD. Если Вы делаете ошибку в любой точке в течение процесса установки RAID, вы можете всегда вернуться сюда, чтобы очистить диск от следов предыдущей попытки.
Замечание
На sparc64 используйте /dev/rwd1c вместо /dev/rwd1d!
#dd if=/dev/zero of=/dev/rwd1d bs=8k count=1
1+0 records in
1+0 records out
8192 bytes transferred in 0.003 secs (2730666 bytes/sec)
После завершения процесса, убедитесь, что на i386 удалена MBR и метки диска NetBSD, а на sparc64 метка диска Sun.
После того, как вы убедились, что второй диск пуст, на i386 необходимо установить MBR используя значения, полученные с Disk0/wd0. Вы должны помнить, что необходимо сделать раздел NetBSD активным, иначе система не будет загружаться. Также вы должны создать метку диска NetBSD на Disk1/wd1, которая будет использоваться для создания и работы RAID. На sparc64 вам необходимо просто воспользоваться disklabel(8) для записи метки диска Sun.
Подсказка
disklabel(8) может использовать переменную среды $EDITOR для установки редактора, в котором будет осуществляться правка. По умолчанию используется vi(1)
На i386:
#fdisk -0ua /dev/rwd1d
fdisk: primary partition table invalid, no magic in sector 0
Disk: /dev/rwd1d
NetBSD disklabel disk geometry:
cylinders: 19386, heads: 16, sectors/track: 63 (1008 sectors/cylinder)
total sectors: 19541088
BIOS disk geometry:
cylinders: 1023, heads: 255, sectors/track: 63 (16065 sectors/cylinder)
total sectors: 19541088
Do you want to change our idea of what BIOS thinks? [n]
Partition 0:
<UNUSED>
The data for partition 0 is:
<UNUSED>
sysid: [0..255 default: 169]
start: [0..1216cyl default: 63, 0cyl, 0MB]
size: [0..1216cyl default: 19541025, 1216cyl, 9542MB]
bootmenu: []
Do you want to change the active partition? [n] y
Choosing 4 will make no partition active.
active partition: [0..4 default: 0] 0
Are you happy with this choice? [n] y
We haven't written the MBR back to disk yet. This is your last chance.
Partition table:
0: NetBSD (sysid 169)
start 63, size 19541025 (9542 MB, Cyls 0-1216/96/1), Active
1: <UNUSED>
2: <UNUSED>
3: <UNUSED>
Bootselector disabled.
Should we write new partition table? [n] y
#disklabel -r -e -I wd1
type: unknown
disk: Disk1
label:
flags:
bytes/sector: 512
sectors/track: 63
tracks/cylinder: 16
sectors/cylinder: 1008
cylinders: 19386
total sectors: 19541088
[...snip...]
16 partitions:
# size offset fstype [fsize bsize cpg/sgs]
a: 19541025 63 RAID # (Cyl. 0*-19385)
c: 19541025 63 unused 0 0 # (Cyl. 0*-19385)
d: 19541088 0 unused 0 0 # (Cyl. 0 -19385)
На i386 слайсы c: и d: зарезервированы. c: представляет собой часть диска, d: представляет собой весь диск. Поскольку мы будем использовать под NetBSD весь диск, слайс a: находится в границах слайса c: и имеют одинаковые размеры и смещение. Смещение должно начаться в границе дорожки (приращение секторов, соответствующих значению sectors/track в метке диска). Однако, на sparc64 c: представляет полный раздел NetBSD и в метке диска Sun d: не зарезервирован. Также обратите внимание, что на sparc64 c: и a: не требуют никакого смещения с начала диска, однако если оно есть, то должно начаться в границе цилиндра (приращение секторов, соответствующих значению sectors/cylinder).
15.3.5. Инициализация устройства RAID
Затем создаем файл конфигурации для RAID. Традиционно он находится в /etc , читается и нициализируется во время загрузки. Но, поскольку мы создаем самозагружаемый том RAID, данные конфигурации будут фактически записаны в том RAID, используя возможность «автоматического выбора конфигурации». Поэтому файлы необходимы только в течение начальной установки и не должны постоянно находиться в /etc.
Обратите внимание, что wd9 – несуществующий диск. Это позволит нам устанавливать том RAID с поддельным компонентом, которым мы несколько позже заменим Disk0/wd0. Независимо от того, устройство в /dev для wd9 должно существовать.
#cd /dev#sh MAKEDEV wd9#cd -
Подсказка
В NetBSD 2.0+ в качестве «поддельного» устройства /dev/wd9a вы можете использовать специальное имя диска «absent».
Затем мы конфигурируем устройство RAID и инициализуем уникальный серийный номер. В этом примере мы используем схему «YYYYMMDDRevision«. Вы можете выбирать формат полностью на свое усмотрение, учтите только, что в нашей схеме не должно быть два набора RAID с одним номером в единицу времени.
После чего мы инициализируем набор RAID, ингнорируя ошибки, связанные с «поддельным» диском.
#raidctl -v -C /var/tmp/raid0.conf raid0
raidlookup on device: /dev/wd9a failed!
raid0: Component /dev/wd9a being configured at col: 0
Column: 0 Num Columns: 0
Version: 0 Serial Number: 0 Mod Counter: 0
Clean: No Status: 0
Number of columns do not match for: /dev/wd9a
/dev/wd9a is not clean!
raid0: Component /dev/wd1a being configured at col: 1
Column: 0 Num Columns: 0
Version: 0 Serial Number: 0 Mod Counter: 0
Clean: No Status: 0
Column out of alignment for: /dev/wd1a
Number of columns do not match for: /dev/wd1a
/dev/wd1a is not clean!
raid0: There were fatal errors
raid0: Fatal errors being ignored.
raid0: RAID Level 1
raid0: Components: /dev/wd9a[**FAILED**] /dev/wd1a
raid0: Total Sectors: 19540864 (9541 MB)
#raidctl -v -I 2004082401 raid0#raidctl -v -i raid0
Initiating re-write of parity
#tail -1 /var/log/messages
raid0: Error re-writing parity!
#raidctl -v -s raid0
Components:
/dev/wd9a: failed
/dev/wd1a: optimal
No spares.
/dev/wd9a status is: failed. Skipping label.
Component label for /dev/wd1a:
Row: 0, Column: 1, Num Rows: 1, Num Columns: 2
Version: 2, Serial Number: 2004082401, Mod Counter: 7
Clean: No, Status: 0
sectPerSU: 128, SUsPerPU: 1, SUsPerRU: 1
Queue size: 100, blocksize: 512, numBlocks: 19540864
RAID Level: 1
Autoconfig: No
Root partition: No
Last configured as: raid0
Parity status: DIRTY
Reconstruction is 100% complete.
Parity Re-write is 100% complete.
Copyback is 100% complete.
15.3.6. Установка файловой системы
Устройство RAID теперь сконфигурирован и доступен. Он является псевдо дисковым устройством. Теперь вам остается определиться с размерами слайсов. В целях упрощения примеров, на нашей системе 8.5 гигабайт выделено для / как /dev/raid0a и все остальное под swap как /dev/raid0b.
Предостережение
Эта схема разбиения диска неподходит для сервера. Руководство NetBSD затрагивает вопрос выделения дискового пространства в Глава 2, Установка.
Замечание
Обратите внимание, что 1 Гб это 2*1024*1024=2097152 blocks (1 блок это 512 байт или 0.5 килобайта). Несмотря на используемое оборудование, в псевдо диске RAID всегда будет 512 байтов/сектор.
Замечание
В этом примере пространство, выделенное слайсу a:, различается между i386 и sparc64, поэтому различается размер томов RAID:
Теперь файловая система RAID готова к использованию. Мы монтируем ее в /mnt и копируем все файлы со старой системы. Это можно сделать, используя утилиты dump(8) или pax(1).
Теперь NetBSD установлена на файловой системе RAID. Мы должны установить точки монтирования в новой копии /etc/fstab иначе не произойдет монтирования разделов. Замените wd0 на raid0.
Раздел подкачки должен быть расконфигурирован перед выключением системы, для избежания ошибок четности на устройстве RAID. Это очень легко сделать добавив одну строку в /etc/rc.conf.
#vi /mnt/etc/rc.conf
swapoff=YES
Затем загрузчик должен быть установлен на Disk1/wd1. Ошибка на этом этапе оставит загрузочным только Disk0/wd0 и сделает RAID-1 бессмысленным в случае отказа загрузочного диска.
Подсказка
Поскольку на многих материнских платах i386 меню BIOS/CMOS может вводить в заблуждение относительно порядка опроса загрузочных устройств, я настоятельно рекомендую использовать опцию начального загрузчика «-o timeout=X». Установка уникального значения для каждого диска позволит точно определить, с какого диска загружается система.
Предостережение
Хотя может казаться логичным установить 1-ый блок начальной загрузки в /dev/rwd1{c,d}, (что являтся идеологически верным для NetBSD 1.6.x installboot(8)) сейчас это не так. Если вы делаете эту ошибку, загрузочный сектор будет поврежден без возможности восстановления и вам придется начать процесс сначала.
На i386 установка загрузчика в /dev/rwd1a :
#/usr/sbin/installboot -o timeout=30 -v /dev/rwd1a /usr/mdec/bootxx_ffsv1
File system: /dev/rwd1a
File system type: raw (blocksize 8192, needswap 1)
Primary bootstrap: /usr/mdec/bootxx_ffsv1
Preserving 51 (0x33) bytes of the BPB
На sparc64 также устанавливаем загрузчик в /dev/rwd1a на флаг «-o» не поддерживается (и ненужен, благодаря OpenBoot):
В заключение, RAID необходимо установить как авто-конфигурируемый и система должна быть перезагружена. После этого все должно монтироваться с устройства RAID.
#raidctl -v -A root raid0
raid0: Autoconfigure: Yes
raid0: Root: Yes
#tail -2 /var/log/messages
raid0: New autoconfig value is: 1
raid0: New rootpartition value is: 1
#raidctl -v -s raid0
[...snip...]
Autoconfig: Yes
Root partition: Yes
Last configured as: raid0
[...snip...]
#shutdown -r now
Внимание
Всегда используйте shutdown(8) для выключения системы. Не используйте просто reboot(8). reboot(8) не совсем корректно отрабатывает скрипты rc и не отключает раздел подкачки. Это приведет к ошибкам четности после каждой перезагрузки.
15.3.8. Первая загрузка с RAID
В этой точке временно сконфигурируйте вашу систему для загрузки с Disk1/wd1. Для получения дополнительной информации обратитесь к Раздел 15.3.10, «Тестирование загрузочной области». Теперь система должна загрузиться и все файловые системы должны находиться на RAID. RAID будет функционален с единственным компонентом, однако набор не реализован полностью, потому что поддельный диск (wd9) считается аварийным.
#egrep -i "raid|root" /var/run/dmesg.boot
raid0: RAID Level 1
raid0: Components: component0[**FAILED**] /dev/wd1a
raid0: Total Sectors: 19540864 (9541 MB)
boot device: raid0
root on raid0a dumps on raid0b
root file system type: ffs
#df -h
Filesystem Size Used Avail Capacity Mounted on
/dev/raid0a 8.9G 196M 8.3G 2% /
kernfs 1.0K 1.0K 0B 100% /kern
#swapctl -l
Device 1K-blocks Used Avail Capacity Priority
/dev/raid0b 262592 0 262592 0% 0
#raidctl -s raid0
Components:
component0: failed
/dev/wd1a: optimal
No spares.
component0 status is: failed. Skipping label.
Component label for /dev/wd1a:
Row: 0, Column: 1, Num Rows: 1, Num Columns: 2
Version: 2, Serial Number: 2004082401, Mod Counter: 65
Clean: No, Status: 0
sectPerSU: 128, SUsPerPU: 1, SUsPerRU: 1
Queue size: 100, blocksize: 512, numBlocks: 19540864
RAID Level: 1
Autoconfig: Yes
Root partition: Yes
Last configured as: raid0
Parity status: DIRTY
Reconstruction is 100% complete.
Parity Re-write is 100% complete.
Copyback is 100% complete.
15.3.9. Добавление Disk0/wd0 в RAID
Теперь мы добавим Disk0/wd0 как компонент RAID. Это уничтожит первоначальную структуру файловой системы. На i386, метка диска MBR не будет затронута (помните, что мы скопировали метку wd0 к wd1), поэтому нет никакой потребности «обнулять» Disk0/wd0. Однако, мы должны повторно маркировать Disk0/wd0, чтобы иметь идентичную метку диска NetBSD, как и на Disk1/wd1. Тогда мы добавляем Disk0/wd0 как «горячее резервирование» к набору RAID и инициализируем реконструкцию четности для всех устройств RAID, фактически добавляя Disk0/wd0 в RAID-1 набор и «синхронизируя» оба диска.
В качестве последней проверки, можно воспользоваться diff(1), чтобы гарантировать соответствие метки диска Disk0/wd0 и Disk1/wd1. Вы должны также зарезервировать эти файлы для изучения в случае аварии.
Как только вы будете готовы, добавьте Disk0/wd0 как резервный компонент и начинайте реконструкцию:
#raidctl -v -a /dev/wd0a raid0
/netbsd: Warning: truncating spare disk /dev/wd0a to 241254528 blocks
#raidctl -v -s raid0
Components:
component0: failed
/dev/wd1a: optimal
Spares:
/dev/wd0a: spare
[...snip...]
#raidctl -F component0 raid0
RECON: initiating reconstruction on col 0 -> spare at col 2
11% |**** | ETA: 04:26 \
В зависимости от имеющихся аппаратных средств, время реконструкции может отличаться. Вы можете наблюдать на другой консоли:
#raidctl -S raid0
Reconstruction is 0% complete.
Parity Re-write is 100% complete.
Copyback is 100% complete.
Reconstruction status:
17% |****** | ETA: 03:08 -
После перезагрузки оба диска должны быть «optimal».
#tail -f /var/log/messages
raid0: Reconstruction of disk at col 0 completed
raid0: Recon time was 1290.625033 seconds, accumulated XOR time was 0 us (0.000000)
raid0: (start time 1093407069 sec 145393 usec, end time 1093408359 sec 770426 usec)
raid0: Total head-sep stall count was 0
raid0: 305318 recon event waits, 1 recon delays
raid0: 1093407069060000 max exec ticks
#raidctl -v -s raid0
Components:
component0: spared
/dev/wd1a: optimal
Spares:
/dev/wd0a: used_spare
[...snip...]
Когда реконструкция закончена, мы должны установить загрузчик на Disk0/wd0. На i386 установка загрузчика в /dev/rwd0a:
#/usr/sbin/installboot -o timeout=15 -v /dev/rwd0a /usr/mdec/bootxx_ffsv1
File system: /dev/rwd1a
File system type: raw (blocksize 8192, needswap 1)
Primary bootstrap: /usr/mdec/bootxx_ffsv1
Preserving 51 (0x33) bytes of the BPB
И снава перезагрузка. Это необходимо для перевода Disk0/wd0 из состояния «used_spare» как «Component0″ в «optimal». Обратитесь к комментариям следующей секции для контроля за состоянием четности после каждой перезагрузки.
#shutdown -r now
15.3.10. Тестирование загрузочной области
В этой точке вы должны гарантировать, что аппаратные средства вашей системы могут должным образом обработать загрузочные блоки на любом диске. На i386 это аппаратно-зависимый процесс, и выполняется через меню CMOS/BIOS или меню конфигурации платы контроллера.
На i386 используется система меню для установки приоритетов загрузки устройств (Disk1/wd1 прежде Disk0/wd0). Приведем пример для Award BIOS.
Рисунок 15.6. Award BIOS i386. Загрузка с Disk1/wd1
Сохраняем изменения и выходим.
>> NetBSD/i386 BIOS Boot, Revision 3.1
>> (seklecki@localhost, Fri Aug 13 08:08:47 EDT 2004)
>> Memory: 640/31744 k
Press return to boot now, any other key for boot menu
booting hd0a:netbsd - starting in 30
Вы можете убедиться, что BIOS читает Disk1/wd1, поскольку таймаут загрузчика составляет 30 секунд вместо 15. После перезагрузки верните настройки BIOS для загрузки по умолчанию:
Рисунок 15.7. Award BIOS i386. Загрузка с Disk0/wd0
Сохраняем изменения и выходим.
>> NetBSD/i386 BIOS Boot, Revision 3.1
>> (seklecki@localhost, Fri Aug 13 08:08:47 EDT 2004)
>> Memory: 640/31744 k
Press return to boot now, any other key for boot menu
booting hd0a:netbsd - starting in 15
Обратите внимание, как ваше ядро обнаруживает controller/bus/drive, независимо от того, что назначает BIOS в качестве загрузочного диска. Это нормальное поведение.
На sparc64 используйте Sun OpenBoot devalias для подтверждения загрузки:
Sun Ultra 5/10 UPA/PCI (UltraSPARC-IIi 400MHz), No Keyboard
OpenBoot 3.15, 128 MB memory installed, Serial #nnnnnnnn.
Ethernet address 8:0:20:a5:d1:3b, Host ID: nnnnnnnn.
ok devalias
[...snip...]
cdrom /pci@1f,0/pci@1,1/ide@3/cdrom@2,0:f
disk /pci@1f,0/pci@1,1/ide@3/disk@0,0
disk3 /pci@1f,0/pci@1,1/ide@3/disk@3,0
disk2 /pci@1f,0/pci@1,1/ide@3/disk@2,0
disk1 /pci@1f,0/pci@1,1/ide@3/disk@1,0
disk0 /pci@1f,0/pci@1,1/ide@3/disk@0,0
[...snip...]
ok boot disk0 netbsd
Initializing Memory [...]
Boot device /pci/pci/ide@3/disk@0,0 File and args: netbsd
NetBSD IEEE 1275 Bootblock
>> NetBSD/sparc64 OpenFirmware Boot, Revision 1.8
>> (lavalamp@j8, Thu Aug 19: 15:45:42 EDT 2004)
loadfile: reading header
elf64_exec: Booting [...]
symbols @ [....]
Copyright (c) 1996, 1997, 1998, 1999, 2000, 2001
The NetBSD Foundation, Inc. All rights reserved.
Copyright (c) 1982, 1986, 1989, 1991, 1993
The Regents of the University of California. All rights reserved.
[...snip...]
И второй диск:
ok boot disk2 netbsd
Initializing Memory [...]
Boot device /pci/pci/ide@3/disk@2,0: File and args:netbsd
NetBSD IEEE 1275 Bootblock
>> NetBSD/sparc64 OpenFirmware Boot, Revision 1.8
>> (lavalamp@j8, Thu Aug 19: 15:45:42 EDT 2004)
loadfile: reading header
elf64_exec: Booting [...]
symbols @ [....]
Copyright (c) 1996, 1997, 1998, 1999, 2000, 2001
The NetBSD Foundation, Inc. All rights reserved.
Copyright (c) 1982, 1986, 1989, 1991, 1993
The Regents of the University of California. All rights reserved.
[...snip...]
При каждой последующей загрузку ядро NetBSD должно выдать сообщение, видимое dmesg(8) как:
raid0: RAID Level 1
raid0: Components: /dev/wd0a /dev/wd1a
raid0: Total Sectors: 19540864 (9541 MB)
boot device: raid0
root on raid0a dumps on raid0b
root file system type: ffs
Как только вы убедитесь, что оба диска загрузочные, проверьте четность RAID после перезагрузки:
#raidctl -v -s raid0
Components:
/dev/wd0a: optimal
/dev/wd1a: optimal
No spares.
[...snip...]
Component label for /dev/wd0a:
Row: 0, Column: 0, Num Rows: 1, Num Columns: 2
Version: 2, Serial Number: 2004082401, Mod Counter: 67
Clean: No, Status: 0
sectPerSU: 128, SUsPerPU: 1, SUsPerRU: 1
Queue size: 100, blocksize: 512, numBlocks: 19540864
RAID Level: 1
Autoconfig: Yes
Root partition: Yes
Last configured as: raid0
Component label for /dev/wd1a:
Row: 0, Column: 1, Num Rows: 1, Num Columns: 2
Version: 2, Serial Number: 2004082401, Mod Counter: 67
Clean: No, Status: 0
sectPerSU: 128, SUsPerPU: 1, SUsPerRU: 1
Queue size: 100, blocksize: 512, numBlocks: 19540864
RAID Level: 1
Autoconfig: Yes
Root partition: Yes
Last configured as: raid0
Parity status: clean
Reconstruction is 100% complete.
Parity Re-write is 100% complete.
Copyback is 100% complete.
Драйвер CCD позволяет пользователю «объединять» несколько физических дисков в один псевдо-диск. В то время, когда RAIDframe (смотри Глава 15, NetBSD RAIDframe) позволяет организовывать массивы RAID level 0 только с одинаковой геометрией, CCD позволяет преодолевать эти ограничения. При работе с CCD возможно «чередование» дисков для повышения быстродействия, но с потерей дискового пространства. В этом примере такую возможность мы не рассматриваем.
Для установка CCD необходимо выполнить несколько шагов:
Установить физический носитель
Сконфигурировать ядро
Метку каждого диска присоединить к CCD
Создать файл конфигурации CCD
Инициализировать устройство CCD
Создать файловую систему на новом устройстве CCD
Примонтировать файловую систему CCD
В этом примере CCD устанавливается на NetBSD/sparc 1.5. CCD будет занимать 4 SCSI диска внешней корзины Sun, подсоединенной через стандартный 50 пиновый разьем SCSI.
14.1. Установка физичесих носителей
Первый Ваш шаг зависит от Вашей платформы и от имеющихся в наличии аппаратных средств.
Вывод моего DMESG:
Disk #1:
probe(esp0:0:0): max sync rate 10.00MB/s
sd0 at scsibus0 target 0 lun 0: <SEAGATE, ST32430N SUN2.1G, 0444> SCSI2 0/direct fixed
sd0: 2049 MB, 3992 cyl, 9 head, 116 sec, 512 bytes/sect x 4197405 sectors
Disk #2
probe(esp0:1:0): max sync rate 10.00MB/s
sd1 at scsibus0 target 1 lun 0: <SEAGATE, ST32430N SUN2.1G, 0444> SCSI2 0/direct fixed
sd1: 2049 MB, 3992 cyl, 9 head, 116 sec, 512 bytes/sect x 4197405 sectors
Disk #3
probe(esp0:2:0): max sync rate 10.00MB/s
sd2 at scsibus0 target 2 lun 0: <SEAGATE, ST11200N SUN1.05, 9500> SCSI2 0/direct fixed
sd2: 1005 MB, 1872 cyl, 15 head, 73 sec, 512 bytes/sect x 2059140 sectors
Disk #4
probe(esp0:3:0): max sync rate 10.00MB/s
sd3 at scsibus0 target 3 lun 0: <SEAGATE, ST11200N SUN1.05, 8808 > SCSI2 0
sd3: 1005 MB, 1872 cyl, 15 head, 73 sec, 512 bytes/sect x 2059140 sectors
14.2. Конфигурирование ядра
Для обеспечения поддержки CCD в ядре должна быть прописана следующая директива (имеется в ядре GENERIC):
pseudo-device ccd 4 # concatenated disk devices
В моем файле конфигурации я также жестко привязал SCSI ID и запись устройства в /dev, дабы чего не вышло.
sd0 at scsibus0 target 0 lun ?
# SCSI disk drives
sd1 at scsibus0 target 1 lun ?
# SCSI disk drives
sd2 at scsibus0 target 2 lun ?
# SCSI disk drives
sd3 at scsibus0 target 3 lun ?
# SCSI disk drives
sd4 at scsibus0 target 4 lun ?
# SCSI disk drives
sd5 at scsibus0 target 5 lun ?
# SCSI disk drives
sd6 at scsibus0 target 6 lun ?
# SCSI disk drives
14.3. Присоединяем метку каждого диска к CCD
Каждый диск, входящий в CCD, нуждается в специализированной файловой системе. В этом примере, для disklabel:
/dev/rsd0c /dev/rsd1c /dev/rsd2c /dev/rsd3c
Замечание
Всегда помните, что метка диска — признак символьного устройства, а не блочного.
Замечание
На всех платформах слайс c является символической записью NetBSD и зарезервирован.
Вероятнее всего Вы захотите удалить старые разделы на дисках, отведенных под CCD. Делается это с помощью команды dd(1):
Если Ваша архитектура подразумевает использование MBR (Master Boot Record) и кроме NetBSD на диске могут оказаться разделы других систем, таких как Windows или Linux, то можно убрать MBR и все разделы с диска, используя команду:
После выполнения этой операции все данные на диске окажутся недоступными. Обратите внимание на занимающий весь диск слайс d на платформе i386 (и некоторых других) и c на остальных (например на sparc). Смотрите «kern.rawpartition» sysctl – «3″ для «d», «2″ для «c».
По умолчанию метка для диска будет выглядеть примерно так:
Вам необходимо будет создать один «slice» для раздела NetBSD на диске. «Slice» должен начинаться со смещением ,по крайней мере, в один цилиндр от начала диска/раздела для размещения специальной CCD disklabel. Смещение должно быть кратно отношению «sectors/cylinder», поэтому «size» будет равен «total sectors» за вычетом 1x «sectors/cylinder». Отредактируйте метку диска соответственно:
#disklabel -e sd0
Замечание
Смещение слайса типа «ccd» должно соответствовать значению «sectors/cylinder»
Замечание
Выполните export EDITOR=[path to your favorite editor] перед редактированием метки диска.
Замечание
Тип слайса должен быть указан как ccd.
Поскольку у нас будет только один слайс на разделе, то Вы можете использовать c, обычно зарезервированный. Измените вашу метку диска на следующее:
Убедитесь в том, что метка записалась. Disklabel попросит вас подтвердить изменения, проявите благоразумие в этом вопросе и вспомните, все ли правильно вы сделали?
14.4. Конфигурирование CCD
Как только все диски соответствующим образом размечены, необходимо создать файл конфигурации /etc/ccd.conf. Этот файл не создается по умолчанию, поэтому вам необходимо создать его. Формат файла представлен ниже:
#ccd ileave flags component devices
Замечание
Если значение «ileave» равно 0, то диски обьединяются, если используется значение, эквивалентное значению «sectors/track», диски чередуются.
Файл конфигурации CCD необходим для функционирования только что созданной файловой системы CCD. Не используйте здесь блочное устройство, необходимо указывать символьное.
14.5. Инициализация устройства CCD
Как только вы почувствовали, что конфигурирование произведено правильно, можно инициализировать устройство, используя команду ccdconfig(8). Конфигурируем:
#ccdconfig -c -f /etc/ccd.conf
Расконфигурируем:
#ccdconfig -u -f /etc/ccd.conf
Инициализация устройства CCD активирует в /dev записи /dev/{,r}ccd#::
Поздравляем, теперь у вас есть работающий CCD. Для конфигурирования устройства CCD при начальной загрузке, добавьте опцию ccd=yes в файл /etc/rc.conf. Вы должны добавить следущую строку в /etc/fstab для монтирования файловой системы при загрузке: