22 September, 2008

Советы и рекомендации по оптимизации системы

Данная заметка посвящена оптимизации работы нашего стального коня под управлением операционной системы GNU/Linux.
В разное время в разных местах постоянно попадались советы по оптимизации ядра Linux и ОС GNU/Linux. Устав от того, как разрастаются в Tomboy'е по заметкам куски текста с различными советами, было решено собрать их все в одном месте.
В первую очередь под оптимизацией я буду понимать отключение ненужных и бесполезных служб, которые, по тем или иным причинам, оказались задействованы системой.
Заводите свои двигатели... :-)

предостережение. все манипуляции с оборудованием Вы выполняете на свой страх и риск. Если где-то как-то Ваше оборудование будет повреждено и/или Ваши данные будут потярены, автор данной заметки ответственности не несёт. Выполняйте только те действия, смысл и последствия которых Вам ясны.

примечание. Данные действия были оппробированы мной на дистрибутиве Ubuntu 8.04 с рабочим окружением GNOME и исходными кодами ядра Linux, модифицированного и патченного разработчиками Ubuntu, но также не исключено применение описанных методов и на других дистрибутивах с другими версиями ядер Linux.

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

_Этап первый_. Оптимизация рабочего окружения:
Этот пункт зависит от того DE(desktop environment), которым Вы пользуетесь. В данном случае речь пойдёт о GNOME.
Чтобы разгрузить машину от момента ввода данных в GDM до загрузки рабочего стола, можно отключить ненужные службы в следующих местах:
System -> Preferences -> Sessions - здесь можно отключить те сервисы, которые стартуют непосредственно при входе с текущего аккаунта
System -> Administration -> Services - а здесь можно отключить сервисы системного уровня

совет. Если Вас достал синий пустой экран в окне мультимедиа-проигрывателя, которое появляется каждый раз при перетаскивании этого окна, запустите в терминале gstreamer-properties и на вкладке Video в Default Output - Plugin выберите X Window System (no XV)

совет. Также в некоторых источниках для ускорения запуска приложений рекомендуют сделать следующее: откройте на редактирование с правами суперпользователя файл /etc/fstab и добавьте строку:
127.0.0.1 localhost.localdomain localhost ИМЯ_ВАШЕГО_ХОСТА
Имя хоста можно узнать, запустив в терминале hostname.


_Этап второй_. Оптимизация сервисов и служб.
Через пункт Services доступны не все службы, установленные в системе.
Установите пакет sysv-rc-conf - данный пакет облегчает включение/отключение служб для различных уровней запуска (runlevels)
Запустите его - sudo sysv-rc-conf и настройте его по Вашему вкусу - для каждого уровня запуска.

совет. Отключайте/включайте только те службы и сервисы, назначение и функционирование которых Вам известно. В противном случае, Вы рискуете остаться без жизненно необходимых системе служб.

примечание. Значение и смысл уровней запуска примерно таковы
0 - выполняет скрипт при выключении системы
1/S - однопользовательский режим (single user mode) аналогичен Safe Mode в Windows.
2 - многопользовательский режим (multiuser mode)
3 - зарезервированно (многопользовательские режимы)
4 - зарезервированно (многопользовательские режимы)
5 - зарезервированно (многопользовательские режимы)
6 - выполнение при при перезагрузки


_Этап третий_. Оптимизация файловых систем накопителей.
Так как во многих дистрибутивах ОС GNU/Linux стандартом де-факто является файловая система ext3, начнём с утилиты tune2fs - утилиты для настройки файловых систем ext-семейства.

примечание. Так как tune2fs является системной утилитой, все манипуляции с накопителями, выполняемые с её помощью, требуют привелегий суперпользователя.

Для начала можно установить метки имеющихся разделов - иногда это бывает очень полезно:
sudo tune2fs -L HOME /dev/sda1
sudo tune2fs -L ROOT /dev/sda2

справка. по умолчанию, при форматировании раздела в ext3, на разделе резервируется 5% от всего объёма для использования приложениями, выполняющихся от имени суперпользователя, этого пространства.
Чтобы изменить это значение, используйте ключи -m X или -r Y, где X - количество процентов резервируемого объёма от общего пространства, а Y - соответствующее количество _блоков_ такого пространства. Например, чтобы установить резерв до 1го %, нужно выполнить:
tune2fs -m 1 /dev/sda2
А чтобы полностью отключить резервирование (это особенно актуально для /home где нет и не может быть файлов суперпользователя), нужно выполнить:
tune2fs -r 0 /dev/sda1 или tune2fs -m 0 /dev/sda1
Также среди полезных ключей:
-с N, который устанавливает количество монтирований, после которых будет произведена проверка ФС утилитой fsck
-C N, который устанавливает _текущее_ количество монтирований, сбрасывая предыдущее значение

совет. Если у Вас появились подозрения на дефекты в ФС, загрузитесь с любого LiveCD и выполните с правами суперпользователя:
fsck -fyv /dev/sdXY
Данное сочетание ключей автоматически проверит файловую систему(-f) на накопителе sdXY, выведет информацию о её состоянии(-v) и, в случае обнаружения ошибок, автоматически попытается исправить их(-y).

Настройка журналирования.
Файловая система ext3 поддерживает следующие режимы журналирования:
journal - все данные и метаданные о состоянии ФС заносятся в журнал перед записью - надёжно/медленно;
ordered - (используется по умолчанию) приоритет журналирования отдаётся метаданным, которые помогут восстановить целостность файловой системы в случае сбоя, но не обязательно сами данные - оптимальное соотношение скорости/надёжности;
writeback - журналирование как данных, так и метаданных осуществляется только после записи - ненадёжно/быстро;

внимание! операция изменения типа журнала корректно применима только для отмонтированного раздела; если планируется изменять корневой или домашний раздел, он должен быть отмонтирован; для этого можно воспользоваться практически любым LiveCD-дистрибутивом.
Настройка журналирования через tune2fs происходит следующим образом:
tune2fs -O has_journaled -o journal_dataТИП /dev/sdXY где ТИП = <> (journal), , , а XY - буква и цифра раздела.
Например, установим режим journal для /home и writeback для /:
tune2fs -O has_journaled -o journal_data /dev/sda1
tune2fs -O has_journaled -o journal_data_writeback /dev/sda2

Не забудьте после этого добавить соответствующую информацию в /etc/fstab:
/dev/sda1 / ext3 data=journal ...
/dev/sda2 / ext3 data=writeback ...

Индексирование директорий.
Также возможно включение режима, при котором, в случае, если иерархия каталогов раздела достаточно громоздка, скорость навигации по разделу немного увеличится.
За это отвечает режим индексирования каталогов. Чтобы включить его, выполните следующую команду:
tune2fs -O dir_index /dev/sda1
а чтобы включить индексирование уже существующих каталогов, выполните:
e2fsck -D /dev/sda1

Конфигурирование файловых систем через /etc/fstab
Через настройку данного файла также возможна некоторая оптимизация. Вот некоторые, достаточно полезные опции для файловых систем семейства ext2/3:
acl - поддержка списка управления доступом POSIX
user_xattr - включение расширенных атрибутов файлов для использования при индексировании
noatime/nodiratime - отключение записи времени последнего доступа для файлов/каталогов (не рекомендуется применять для корневого раздела, т.к. работа некоторых программ полагается на это время)
barrier=1 - команда очистки кэша
commit=N - запись данных и метаданных каждые N секунд. По умолчанию N=5.
async(по умолчанию)/sync - весь ввод/вывод данных файловой фс происходит а/синхронно. Синхронный режим не рекомендуется для устройств с ограниченным циклом записи (flash/SSD)
dirsync - все обновления данных, связанные с каталогами, происходят синхронно.

Значения dump и pass
Запись используется утилитой dump для того чтобы решить, когда делать резервную копию. Будучи установленной (хотя во множество дистрибутивов dump по умолчанию не входит), dump проверяет эту запись при загрузке и использует число, чтобы решить, надо ли делать резервную копию. Возможные значения поля - 0 и 1. Если 0, то dump игнорирует файловую систему, если 1, то dump сделает резервную копию.
Запись используется утилитой fsck при загрузке. В зависимости от числа определяется порядок проверки файловой системы. Возможные значения:
0 - не проверять
1 - высший приоритет
2 - приоритет ниже по сравнению с 1

Настройка временных файловых систем.
Если корневой раздел находится на накопителе с ограниченным числом циклов записи (flash/SSD), но при этом Вы не используете падкие на оперативную память приложения и Вам её хватает, то имеет смысл разместить временные разделы системы прямо в оперативной памяти. Для этого в /etc/fstab достаточно добавить следующие строки:
tmpfs /tmp tmpfs defaults,noatime,nodiratime 0 0
tmpfs /var/tmp tmpfs defaults,noatime,nodiratime 0 0
tmpfs /var/log tmpfs defaults,noatime,nodiratime 0 0

Установка параметра интенсивности обращения к swap'у.
За тонкую подстройку ядра и его параметров при работе отвечает служба sysctl. У неё есть достаточно много опций, но в данный момент рассмотрим только одну из всех возможных: vm.swappiness=N, где N - число от 0 до 100, обозначающее интенсивность обращения к swap-разделу. Чтобы сохранить изменения и при следующем запуске, добавьте строку vm.swappiness=N в конец файла /etc/sysctl.conf и сохраните изменения. Оптимальным считается N в районе от 15 до 40.


_Этап четвёртый_. Оптимизация ядра.
Данный этап повлияет не только на работу всей системы, но и позволит значительно сократить процесс загрузки системы.
Каноническая упрощённая схема загрузки ядра Linux приблизительно такова. Сначала грузится vmlinuz, который содержит базовый образ ядра. Потом initrd "передаёт" загружаемому ядру из файла initrd те модули, которые ему необходимы, чтобы дотянуться до корневой файловой системы и подключить модули уже из /lib/modules. И после этого, ядро, со всеми подключёнными внешними модулями, начинает запускать сервисы.
Однако, если пересобрать ядро без поддержки initramfs, но включить все те модули, которые необходимы ядру, чтобы "дотянуться" до корневого раздела, в само ядро (т.е. не "модулем", а вкомпилировать - за это отвечает опция "y" вместо "m" в конфигурационном файле ядра), то этап загрузки, включающий запуск initrd системе не понадобится - ядро сможет загружаться без его участия и, надо сказать, в разы быстрее. Кроме того, пересборка ядра - достаточно хорошая возможность во-первых, узнать лучше своё имеющееся оборудование, во-вторых, чуть лучше разобраться во внутреннем устройстве работы ядра, в-третьих, получить ядро, заточенное под Ваше оборудование и Ваши нужды без кучи лишних дополнительных модулей, поддерживающих ненужное экзотическое оборудование.
Далее не последует подробнейшей инструкции по компиляции и установке ядра; необходимые сведения Вы можете найти здесь:
http://linux4u.jinr.ru/docs/add04/kernel-2.6-install-2.0.html
http://mydebianblog.blogspot.com/2006/12/blog-post_20.html

Но некоторые советы я всё же дам:

-во время конфигурирования ядра Вам наверняка не раз понадобиться узнать подробные сведения о том или ином оборудовании, чтобы включить поддержку только этого оборудования и отключить модули, отвечающие за оборудование, которого у Вас нет и не предвидится. В этом могут помочь следующие утилиты:
*hwinfo - выводит информацио об оборудовании
*dmidecode - выводит информацию об оборудовании, доступную через BIOS
*lspci - выводит информацию об оборудовании, подключённом через шину PCI
*lsusb - выводит информацию об оборудовании, подключённом через шину USB
*lshw - выводит информацию об оборудовании, подобно hwinfo
*hdparm - выводит информацию о жёстких дисках и позволяет их настраивать
*hddtemp - выводит информацию о температуре жёстких дисков
*smartctl - выводит информацию о жёстких дисках с помощью технологии S.M.A.R.T.
*discover - выводит информацию об оборудовании, подобно hwinfo
*sysctl - выводит информацию о службе ядра
*hardinfo - GTK-утилита, подобная hwinfo и подобным.

Например, чтобы узнать информацию об установленных модулях оперативной памяти, выполните:
sudo dmidecode -t memory
А чтобы, например, узнать модель установленной видеокарты, выполните:
hwinfo --gfxcard
За дополнительной информацией просьба обращаться в соответствующие man-страницы.

-чтобя ядро наиболее эффективно использовало всю установленную оперативную память, добавьте в строке загрузчика (GRUB/LILO) параметр ядра mem=M, где - в мегабайтах, точное количество имеющейся оперативной памяти

-если Вас по какой-то причине не устраивает разрешение на виртуальных терминалах tty[1-6] по умолчанию, то за его настройку отвечает параметр ядра vga; чтобы установить нужное разрешение, добавьте vga=XYZ, где XYZ - необходимый режим разрешения; таблица режимов с их кратким описанием доступна здесь - http://en.wikipedia.org/wiki/VESA_BIOS_Extensions#Linux_video_mode_numbers
примечание. На некоторых машинах для корректной работы ядра с параметром vga ядро должно быть скомпилированно (причём в некоторых случаях поддержки модулем не достаточно - необходимо включение _не модулем_) с поддержкой видеодрайвера vesa и видеорежима framebuffer.

-также, для уменьшения скорости загрузки самого ядра, добавьте в строке загрузчика параметр ядра clocksource=hpet.
справка. Параметр clocksource отвечает за то, какой тип таймера будет использоваться ядром для отсчитывания своих тактов. На данный момент, помимо hpet, существуют tsc и 8254, но т.к. hpet является более "современным", его работа может (конечно, в зависимости от оборудования) уменьшить скорость загрузки

-чтобы дать ядру собственное имя, отредактируйте Makefile и в самом начале исправьте строчки типа
EXTRAVERSION = .3
NAME = Err Metey! A Heury Beelge-a Ret!
на что-то вроде
EXTRAVERSION = -3.1-mykernel
NAME = GNU/Linux

-при конфигурировании ядра, чтобы после запуска оно смогло дотянуться до корневого раздела без init-образа, нужно отключить "Device drivers -> ATA/ATAPI/MFM/RLL support" и включить "Device drivers -> Serial ATA (prod) and Parallel ATA (experimental) drivers" (не модулем), потом зайти в этот раздел и включить поддержку Вашего чипсета/контроллера, а также нужно включить (опять же, не модулем) в разделе "Device drivers -> SCSI device support" опции "SCSI disk support", "SCSI CDROM support" и "SCSI generic support". Эти требования обуславливаются тем, что современные версии ядер Linux используют для доступа к накопителям (независимо от их реального физического типа) эмуляцию SCSI-устройств; в противном случае ядро не сможет подключить корневой раздел. Также не забудьте включить не модулем драйвер той файловой системы, которая используется на корневом разделе. Проверьте также, отключён ли пункт Kernel Debugging в меню Kernel Hacking - его _включение_ _существенно_ замедляет загрузку и работу ядра.

-собственно, самое главное - _отключите_ параметр Initial RAM filesystem and RAM disk (initramfs/initrd) support.

-остальные пункты конфигурации - по вкусу, в зависимости от Вашего оборудования :-)

-скомпилировать ядро с последующей перезагрузкой можно, выполнив с правами суперпользователя:
make all && make modules_install && make install && reboot

-если Вы собираете и устанавливаете ядро вручную (т.е. не через пакетный менеджер Вашего дистрибутива), то не забудьте проверить, скопировался ли после компиляции получившийся файл vmlinuz в каталог /boot и добавилась ли запись о свежем ядре в файл menu.lst

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

P.S. Если вдруг Вы это прочитали, но Вам известны какие-то другие краткие, но полезные советы по оптимизации системы, то, пожалуйста, поделитесь ими в комментариях. Если совет действительно будет полезен и Вы не будете возражать, то я обязательно добавлю его в эту заметку.

02 November, 2007

Шифрование домашнего раздела в GNU/Linux. Ещё одна инструкция.

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

Примечание. Перед началом операции во-первых, НАСТОЯТЕЛЬНО рекомендуется сбэкапить все важные данные. Во-вторых, перед вводом команд необходимо перейти в режим суперпользователя.

В попытках найти уже существующие решения, наткнулся на три статьи, но ни одна из них не покрывала мою задачу так, как это нужно мне:
Tuxedo Live - ряд ошибок, в том числе грубых; некоторые команды и применённые принципы не пояснены.
Прикладная Дебианавтика - инструкция правильная, но слишком исчерпывающая; решение описано скорее для серверных машин с применением LVM-разделов.
Продвинутый способ шифрования разделов в Linux@Форум "Античат" - пособие грамотное, но слишком уж параноидальное. Единственное, что оттуда подчерпнул - инструкция о том, как забить раздел случайными данными и как узнать, сколько ещё осталось:
узнаём PID процесса: ps ax | grep "dd if"; а затем получаем информацию о том, сколько случайных данных уже записано: kill -USR1 pid

Приступим.
0. Устанавливаем необходимые пакеты. Для шифрования будут использоваться cryptsetup, dm-crypt и fuse-utils.
1. Форматируем будущий домашний раздел в целевую файловую систему.
2. Забиваем раздел случайными данными; в этом случае, во-первых, раздел будет видиться всеми программами для работы с дисками и разделами как ошибочный; во-вторых, практически невозможно будет установить точный объём занятого непосредственно данными пространства из-за того, что для программ по обслуживанию дисков весь раздел будет забит мусором, а, следовательно, будет занят весь раздел без возможности однозначного установления, где заканчиваются данные и начинается свободное пространство, забитое мусором.

Примечание: наполнение раздела случайными данными - очень длительная процедура. В моём случае домашний раздел на 60GB наполнился за 5-8 часов. Т.е. в этом случае имеет смысл сделать такую процедуру перед сном. Тогда на утро раздел будет готов.

3. Шифруем домашний раздел; с необходимыми параметрами шифрования и паролем.
4. Редактируем любимым текстовым редактором файл /etc/crypttab в соответствии с параметрами шифрования.
5. Перезапускаем службу шифрования дисков cryptdisks. Если всё правильно, то появится предложение ввести пароль. Если пароль введён правильно и нигде нет ошибок, то служба шифрования успешно перезапустится. Если нет, то появится предупреждение или ошибка. Значит где-то что-то неправильно.
6. Форматируем уже зашифрованный домашний раздел в целевую файловую систему.
7. Редактируем, опять же, любимым текстовым редактором, /etc/fstab таким образом, чтобы в качестве домашнего раздела монтировался свежезашифрованный раздел.
8. Монтируем зашифрованный будущий домашний раздел.
9. Копируем на него структуру раздела /home без изменений.
10. Перезагружаем систему, вводим при загрузке пароль и работаем с домашним зашифрованным разделом на отдельном логическом диске.

Подведём итоги. Собственно, сами команды:
{
/dev/sdaN - раздел, который будет зашифрован и станет домашним;
name - имя, эдакая метка зашифрованного раздела.
В моём случае N=3; name=home; файловая система - ext3; текстовый редактор - vim
}
0. apt-get install dmsetup cryptsetup fuse-utils
1. mkfs -t ext3 /dev/sdaN
2. dd if=/dev/urandom of=/dev/sdaN
3. cryptsetup -c aes-cbc-essiv:sha256 -s 256 luksFormat /dev/sdaN
YES
вводим два раза пароль для зашифровки раздела
4. vim /etc/crypttab
добавляем строчку:
name /dev/sdaN none luks,cipher=aes-cbc-essiv:sha256
5. /etc/init.d/cryptdisks restart
6. mkfs -t ext3 /dev/mapper/name
7. vim /etc/fstab
комментируем строку с /home, если она была;
добавляем другую:
/dev/mapper/name /home ext3 defaults
8. mkdir /mnt/home; mount /dev/mapper/name /mnt/home
9. cp -rfax /home/* /mnt/home/
10. reboot
когда очередь дойдёт до монтирования файловых систем, автоматически запустится служба cryptdisks и попросит ввести пароль от зашифрованного домашнего раздела:
11.Enter LUKS passphrase:
Введя правильный пароль, раздел подмонтируется.
При вводе неправильного пароля предложение о вводе пароля будет выводиться снова и снова.
Но если монтировать зашифрованный раздел не требуется, то достаточно нажать ctrl-d при предложении ввести пароль - загрузка системы продолжится без монтирования зашифрованного раздела.

Дополнение.
Вполне может возникнуть необходимость доступа к зашифрованному разделу с LiveCD-дистрибутива, когда, к примеру, загрузка с корневого раздела невозможна. В этом случае (пример для deb-систем):
1. редактируем /etc/apt/sources.list, чтобы было доступно как можно больше репозитариев
2. обновляем список доступных пакетов:
#apt-get update
3. устанавливаем дополнительные пакеты:
#apt-get install dmsetup cryptsetup fuse-utils
4. подключаем модуль ядра для работы с зашифрованными разделами:
#modprobe dm_crypt
#modprobe dm-crypt
Если подключение модулей прошло успешно, то не будет выведено никакой информации; если же что-то пошло не так, то, скорее всего, ядро в комплекте LiveCD-дистрибутива данного модуля в наличии не имеет - придётся поискать другой дистрибутив
5. редактируем /etc/crypttab:
name /dev/sdaN none luks,cipher=aes-cbc-essiv:sha256
6. перезапускаем службу:
#/etc/init.d/cryptdisks restart
на запрос вводим пароль от зашифрованного раздела
7. монтируем уже подмонтированный :-) зашифрованный раздел в работающую файловую систему:
#mkdir /mnt/disk && mount -t ext3 /dev/mapper/name /mnt/disk
Доступ к зашифрованному разделу с данными получен.

Примечание.
Возможно, периодически эта страница будет обновляться тематической информацией по шифрованию. Таким образом, планируется из данного поста сделать что-то вроде смеси wiki-страницы с miniHOWTO по шифрованию в GNU/Linux и тому, что с этим связано. В качестве анонса следующего обновления - изменение алгоритма шифрования паролей по умолчанию MD5 на что-нибудь другое (либо DES, либо Bluefish), а также шифрование не всего раздела, а отдельных каталогов, доступных пользователю, через EncFS. Как говорится, coming soon... :-)

08 April, 2007

Предисловие

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