настройка видеокарты в линукс
Установка видеокарт в linux
Материал из Пингвиньи радостей
Содержание
Статья с описанием установки видеокарт Linux
Статья содержит общие элементы описания установки видеокарт в Linux.
Описание настройки отдельных типов видокарт приведено в статьях
(Как правило) Видеокарты могут работать в текстовом режиме, в графическом режиме с поддержкой 2D/3D ускорения, в том числе на уровне аппаратного ускорения.
Текстовый режим видеокарт
Для запуска операционной среды linux в текстовом режиме (режим командной строки) дополнительных действий не требуется.
Обзор графических режимов
Графический режим VESA
Драйвер vesa может быть использован, если видеокарта поддерживает стандарт VESA. (На текущий момент) Нам неизвестны видеокарты не поддерживающие данный стандарт. Последние версии драйвера vesa (например в debian squeeze с xorg версии 7.5) обеспечивают поддержку и 2D/3D ускорения.
Для подключения драйвера
Поддержка аппаратного ускорения
Поддержка аппаратного ускорения, как правило, может быть обеспечена драйверами изготовителя. Часто это самая простая или единственная возможность. Но бывают случаи, когда изготовитель «забросил» поддержку определённой видеокарты или предлагает драйвера для «другой» операционной среды. В этом случаев ускорение может быть достигнуто с помощью драйверов включённых в поставку Xorg. Поэтому способы поддержки аппаратного ускорения для разных моделей видеокарт даже для одного изготовителя могут серьзёно различаться.
Как включить дискретную видеокарту на Linux
В этой заметке мы рассмотрим следующие вопросы:
Установлен проприетарный драйвер NVIDIA, но видеокарта не используется
К сожалению, вопросы установки проприетарных драйверов для видеокарт на Linux до сих пор не так безболезненны, как на Windows. Но я столкнулся с ещё более запутанной ситуацией: после успешной установки драйверов, не получается задействовать, использовать видеокарту NVidia.
Симптомы проблемы следующие:
Чуть подробнее о последнем пункте. Для меня видеокарта представляет главный интерес для брут-форса (взлома) хешей паролей. И эта функция работает, видеокарта нагружена, Hashcat показывает устройство видеокарты как успешно используемое, высокая скорость брут-форса паролей. Именно по этой причине я уже полтора года (!) после установки проприетарного драйвера NVidia не догадывался, что у меня какие-либо проблемы.
И всё-таки драйвер NVidia работает
Я могу убедиться в этом, поскольку срабатывала команда
А также успешно работали приложения, использующие CUDA. Для всех других задач я не мог задействовать видеокарту NVidia.
Какую видеокарту, встроенную в центральный процессор или выделенную выбирает Linux?
Некоторые видеокарты от NVidia поддерживают технологию NVIDIA Optimus. Суть этой технологии в том, что программное обеспечение автоматически переключается на интегрированную (Intel) или выделенную (NVidia) видеокарту. На таких системах всё довольно просто — по крайней мере в теории. Нужная видеокарта может выбираться множество раз во время работы Linux.
Но на компьютерах без NVIDIA Optimus видеокарта выбирается настройками пользователя, либо по умолчанию используется графика Intel.
Как узнать, какая видеокарта используется в Linux
Есть несколько команд, которые покажут, какая видео карта используется:
Эта же самая команда, но запущенная через optirun из пакета Bumblebee:
Пример вывода, в котором показано, что задействована видеокарта NVIDIA:
Подробнее о optirun и Bumblebee будет позже.
Ещё одна команда, которая выводит информацию об используемой видеокарте (и прикольный треугольник в качестве бонуса):
С помощью команды lspci и определённых опций можно вывести информацию об устройствах, на конце строки с используемой видеокартой должно быть [VGA controller]. Команда для фильтрации данных:
Как проверить, используется ли видеокарта NVIDIA
Следующая команда покажет процессы, которые использует видеокарта NVIDIA (если процессов нет, значит видеоадаптер не используется):
Ещё одна команда, которая показывает процессы, потребляющие ресурсы видеокарты NVIDIA, а также уровень её загруженности, температуру и другие метрики:
Как установить видео драйвер NVidia в Linux
Для установки проприетарного драйвера NVidia в Kali Linux выполните команды:
Возможно, этот же способ будет работать и для Debain и других производных.
Для установки драйвера NVidia в Arch Linux, BlackArch и их производные выполните команду:
Кроме указанных, дополнительно будут установлены пакеты nvidia-utils и opencl-nvidia. Если вам не нужен CUDA, то не устанавливайте пакет cuda.
Как установить и пользоваться Bumblebee (как включить NVIDIA Optimus в Linux)
Пакет Bumblebee нужен для автоматического переключения между интегрированной и дискретной видеокартами. Ваша карта должна поддерживать технологию NVidia Optimus, список поддерживающих карт вы можете найти на этой странице: https://www.geforce.com/hardware/technology/optimus/supported-gpus
Если ваша карта там есть, то переходите к выполнению следующих команд. У вас уже должен быть установлен проприетарный драйвер NVIDIA, как это показано выше.
На Kali Linux, Debian и их производных выполните:
В ПРОЦЕССЕ ПОДГОТОВКИ
На Arch Linux, BlackArch и их производных выполните:
Система зависает после установки Bumblebee
Я столкнулся с проблемой, что Bumblebee в принципе работает, но при использовании некоторых команд, которые задействуют CUDA или обращаются к модулям ядра, система зависала. Чтобы проверить, есть ли у вас эта проблема, выполните команду lspci, например:
Если система полностью зависнет, то перезагрузитесь и удалите пакет bbswitch.
Вместо удаления bbswitch вы можете попробовать в опции загрузки ядра добавить строку:
Для этого создайте файл /etc/modprobe.d/options.conf:
и скопируйте в него:
Но у меня сработало только удаление bbswitch.
Как пользоваться Bumblebee / NVIDIA Optimus в Linux
Теперь любую программу, которая должна использовать видеокарту NVIDIA, можно запустить командой вида:
Когда optirun не используется, то карта NVIDIA должна находиться в отключённом состоянии, что должно сберегать электричество.
Как проверить Bumblebee / NVIDIA Optimus в Linux
Запустите тест видеокарты обычной командой:
А также с помощью optirun:
Обратите внимание, что FPS вырос примерно в 20 раз.
Ещё один вариант теста работы видеокарты:
А также с помощью optirun:
Вы должны увидеть прирост производительности при использовании optirun.
Во время работы этих тестов, выполните команду:
Вы должны увидеть процессы, которые используют дискретную видеокарту.
Если у вас установлен веб-браузер Chromium, то запустите его двумя способами:
В обоих случаях откройте вкладку:
Там вы увидите информацию об используемом графическом чипе:
Заключение
Даже после написания этой инструкции, после того, как я разобрался во многих вопросах, всё ещё осталось много непонятного.
Например, как использовать постоянно только карту NVidia? Ниже я покажу что именно пробовал — абсолютно всё не сработало.
Также открыт вопрос, как установить Bumblebee в Debian и производные дистрибутивы? Все команды, которые я пробовал, приводят к чёрному экрану, либо неработоспособности Bumblebee.
БОНУС. Как сделать видеокарту NVidia используемой по умолчанию в Linux
В этом разделе я перечислил то, что у меня не сработало — поэтому можете пропускать этот раздел.
Предупреждение: если после указанных в этом разделе действий вы не можете загрузиться — появляется чёрный экран, то во время неудачной загрузки нажмите Ctrl+Alt+F*, где вместо звёздочки пробуйте указать разные цифры, например, Ctrl+Alt+F1, Ctrl+Alt+F2 и т. д., пока не появится консоль. Введите ваш логин и пароль и откатите изменения, которые привели к неудачной загрузке. Для удаления пакетов используйте стандартные менеджеры пакетов вашего дистрибутива, а для редактирования файлов в командной строке используйте vim или nano. Если вы не знакомы с vim или nano, то пропустите этот раздел!
Если драйвер NVidia установлен, то, вроде бы, видеокарта NVidia должна использоваться по умолчанию. У меня это никогда не происходило, всегда используется интегрированная графика Intel.
Начните с проверки настроек БИОСа — там может быть возможность отключить одну из карт.
Для явного указания используемого драйвера можно создать файл /etc/X11/xorg.conf.d/20-nvidia.conf.
И скопировать в него примерно следующее:
Но у меня не происходит загрузка в графический интерфейс.
Если вы хотите отключить загрузку драйверов Intel, то создайте файл /etc/modprobe.d/blacklist-intel.conf:
И скопируйте в него примерно следующее (название модулей могут отличаться в зависимости от вашего центрального процессора):
Среди других советов встречаются добавить в опции загрузки ядра следующее:
Если у вас EFI (а не БИОС), то для изменения опций загрузки ядра нужно открыть файл вида /boot/loader/entries/*.conf. У меня этот файл называется /boot/loader/entries/arch.conf:
Также рекомендуют изменить файл /mkinitcpio.conf:
В котором вместо строки
нужно записать строку
Затем нужно пересобрать ядро, для этого в Debian и производных нужно выполнить команду:
а в Arch Linux и производных нужно выполнить такую команду:
Настройка видеокарты Linux через Xorg
За отрисовку всех графических элементов в Linux отвечает графический сервер. Он реализует интерфейс прослойки между драйверами видеокарты и различными программами, которые работают с графикой.
В самых современных дистрибутивах на замену Xorg серверу пришел новый дисплейный сервер Wayland. Но он все еще находится в активной разработке и не совсем готов к постоянному использованию. Поэтому Xorg все еще применяется в большинстве дистрибутивов.
После установки видеокарта работает достаточно хорошо и настроек по умолчанию в большинстве случаев хватает, но иногда нужно изменить некоторые параметры. Мы не будем рассматривать установку драйверов. В этой статье мы сосредоточимся на том, как выполняется настройка видеокарты linux через xorg.conf.
Настройка видеокарты Linux c помощью xorg.conf
Но настройка xorg linux может все еще понадобиться, если вы хотите сделать нестандартные настройки, повысить частоту обновления экрана, изменить расширение экрана, увеличить производительность и многое другое.
Создание Xorg.conf
Обычно, этот файл размещен в директории /etc/X11/xorg.conf. Но если в вашем дистрибутиве его нет, можно без проблем создать xorg.conf на основе журнала.
Сначала скопируйте файл журнала для новой сессии:
cp /var/log/Xorg.0.log /var/log/Xorg.1.log
Программа проанализирует файл лога, и на его основе создаст новый файл /etc/X11/xorg.conf учитывая конфигурацию вашей системы. В вашем домашнем каталоге появиться файл xorg.conf.new, который нужно скопировать в /etc/X11/:
cp xorg.conf.new /etc/X11/
Синтаксис конфигурационного файла
Перед тем как переходить к настройке xorg.conf нужно разобраться в его синтаксисе, чтобы вы могли немного ориентироваться в самом файле. X сервер отвечает за все интерактивные связи во время сессии. Поэтому конфигурационный файл разбит на секции, несколько из них отвечают за работу с дисплеем, другие за мышь и клавиатуру. Рассмотрим основные секции файла:
Настройка экрана xorg
Большинство параметров вашего экрана система получает с помощью технологии EDID или Extended Display Identification Data. Это информация, переданная дисплеем видеокарте. Здесь обычно содержится модель, производитель, такйминги, разрешение и размер дисплея. Xorg использует эти параметры для выбора оптимального разрешения экрана и глубины цвета.
Но иногда информация из EDID может быть неточной или неверной. Тогда вы можете установить нужные параметры вручную через xorg.conf. Но будьте осторожны, если ваш экран не поддерживает некоторые параметры, вы можете его повредить. Характеристики каждого отдельного устройства можно найти в интернете или же в инструкции от производителя.
Например, вот секция Monitor с настройкой вертикальной и горизонтальной частот, а также разрешения:
Добавив такие опции в секцию Device, вы можете отключить использование EDID:
Option «UseEDIDFreqs» «FALSE»
Option «UseEDIDDpi» «FALSE»
Option «ModeValidation» «NoEdidModes»
Настройка видеокарты в xorg.conf
У драйверов видеокарт ест множество различных полезных опций, которые вы можете настроить с помощью xorg.conf. Большинство из них специфичны для конкретного производителя видеокарт. Например, есть множество настроек для видеокарт NVIDIA, но с другой стороны карты от ATI не настраиваются через этот файл. Драйвера с открытым исходным кодом от Intel имеют только несколько настроек. Дальше будет рассмотрена настройка видеокарты linux для различных производителей.
Настройка Nvidia
У видеокарт NVIDIA есть множество настроек, которые можно указать в xorg.conf. Каждая строка состоит из ключа и значения, ее можно разместить в секции Screen или Device:
Настройка видеокарты Intel
Графическими картами от Intel не всегда поддерживается настройка xorg.conf. Поэтому вам нужно проверить каждую из опций чтобы увидеть дает ли она какой-либо результат. Опции нужно добавлять в раздел Device:
Решение проблем xorg.conf
Но драйвер Vesa работает намного медленнее, чем более современные драйвера. Если Vea позволяет запустить графическое окружение, значит проблема в вашем графическом драйвере или в настройке.
Попробуйте использовать утилиту lspci, чтобы посмотреть точную версию своей видеокарты, обычно для старых карт нужны более старые драйвера.
Выводы
Теперь вы знаете достаточно и настройка видео Linux с помощью xorg не должна для вас быть очень сложной, даже если вы раньше этим не занимались. Особенно, если вы недовольны текущими настройками. Настройка x сервера поможет вам получить больше от старого оборудования или интегрированных карт. Только не забывайте делать резервные копии перед внесением каких-либо изменений.
Электрический блогнот
мои заметки на полях
контроль и разгон графических карт NVIDIA в Linux
Многие геймеры, майнеры и просто любители повозиться с multimedia давно используют видеокарты NVIDIA для своих целей. Используют на «всю катушку». Разработчики видеокарт позволили простым людям создавать программы для запуска на видеокартах, используя мощь всех CUDA ядер. Попутно видеокарты стали комплектоваться оперативной памятью в несколько гигабайт. После этого простая видеокарта превратилась в компьютер-в-компьютере. Поэтому контроль графических карт NVIDIA является первостепенной задачей для тех, кто хочет выжать по максимуму и одновременно добиться того, чтобы карта работала, как можно дольше.
nvidia-smi
Для контроля состояния видеокарты мы будем использовать утилиту nvidia-smi (NVIDIA System Management Interface), которая входит в комплект драйверов производимых компанией NVIDIA для своих карт.
Если у вас Linux, то после установки NVIDIA драйверов nvidia-smi можно найти в папке:
Nvidia-smi является консольной программой (у нее нет графического интерфейса) и для ее запуска необходимо воспользоваться командной строкой.
Полезные команды
С моей точки зрения самой полезным способом запуска nvidia-smi, является запуск без параметров:
вы получите много полезной информации структурированной в виде простенькой таблички. Давайте запусти несколько приложений нагружающих видеокарты и посмотрим, что выдаст nvidia-smi. Для этого воспользуемся примерами, которые поставляются вместе с NVIDIA Cuda Toolkit (установка этого Toolkit описана здесь). Эти примеры точно нагрузят нашу видеокарту 🙂 А так же запустим конвертирование видео из одного формата в другой с помощью утилиты FFmpeg, которая проводит кодирование/раскодирование видео на графическом ускорителе видеокарты.
Глядя на скриншот мы видим, что у нас запущены 4 приложения использующих ресурсы видеокарты:
Шапка таблицы дает информацию о названии видеокарты, версии драйвера, текущем режиме работы и температуру. Все дается в понятном виде и дополнительных объяснений не требует. Рассмотрим подробнее раздел Processes, здесь каждый процесс имеет 5 параметров:
Чтобы получить максимум информации о состоянии видеокарты наберите:
вывалится огромная «простыня», где вы найдете всю информацию про вашу карточку.
Если установлено несколько видеокарт в системе и нужно получить информацию о какой-то карте конкретно, то нужно указать ID этой карты:
Для того, чтобы получить весь список видеокарт в системе воспользуйтесь командой:
Журнал
Для контроля состояния видеокарты в течение некоторого промежутка времени поможет журнал или log. Nvidia-smi позволяет выводить информацию о требуемых параметрах на экран или в файл для последующего анализа.
Следующая команда будет непрерывно с интервалом в 5 секунд выводить на экран информация о потреблении видеопамяти и температуре GPU:
С помощью опции «-f» можно перенаправить вывод в файл:
Еще один способ смотреть за видеокартой — это запустить nvidia-smi с ключами dmon или pmon.
С помощью dmon можно следить за общими параметрами видеокарты. Я чаще всего использую dmon для контроля загруженности чипов NVDEC/NVENC расположенных в карте NVIDIA и которые отвечают за кодирование и раскодирование видео на аппаратном уровне.
Если хотите журналировать потребление ресурсов видеокарты каждым прорцессом, то можно воспользоваться опцией pmon.
Driver Persistence
Peristence — постоянство. Если приложению нужна видеокарта, то обращение происходит сначала к драйверу, а от драйвера к видеокарте. Современные системы могут выгружать драйверы из памяти (например, понизить энергопотребление). Если приложение требует драйвер, а драйвер в это время выгружен, то система загружает драйвер. На это уходит время. Возникает лаг (lag). Чтобы лагов не было, есть возможность сделать драйвер невыгружаемым:
проверяем статус драйвера»
для того, чтобы вернуть все как было (разрешить выгружать драйвер) делаем:
и сразу же проверяем:
Следует помнить, что если вы меняли настройки видеокарты (частоту, энергопотребление), то перевод/вывод ее в Persistence сбросит все предыдущие настройки.
Разгон
По умолчанию разгон выключен. Вы не можете контролировать частоту графического процессора:
ни скорость вентилятора на видеокарте:
Для того, чтобы в nvidia-settings появилась возможность разгона, нужно добавить в файл
в секцию Section «Device» строку:
и перезагрузить компьютер. После перезагрузки в nvidia-settings станут доступны следующие опции для регулировки разгона:
настройка частоты графического процессора
настройка скорости вращения вентилятора
Следует помнить, что разгон переводит видеокарту в нестандартный режим работы и поэтому контроль ее состояния нужно осуществлять еще тщательнее.
Заключение
В данной заметке мы рассмотрели, как осуществлять контроль и разгон графических карт NVIDIA в Linux. Затронули только самые базовые принципы и лишь слегка погрузились в эту интересную тему. На простых примерах посмотрели, как следить за состоянием видеокарты, как вести логи. Слегка коснулись темы разгона. Правда зачастую уже и этого достаточно, чтобы грамотно задействовать мощь видеокарты.
Стань повелителем загрузки Linux
Сначала мы познакомимся с udev и научимся с его помощью исследовать установленные в компьютере устройства прямо во время загрузки: в качестве примера будем автоматически выбирать настройки видеокарт для Xorg. Затем решим задачу работы с одним образом на десятках компьютеров одновременно путём внедрения собственного обработчика в initramfs, а заодно оптимизируем систему для сетевой загрузки. Чтобы дополнительно уменьшить время загрузки и снизить нагрузку на сеть попробуем NFS заменить на NBD, и помочь TFTP с помощью HTTP. В конце вернёмся в начало — к загрузочному серверу, который также переведём в режим «только для чтения».
Данная статья — скорее исследование, а не готовое руководство (все решения работают, просто они не всегда оптимальны). В конце у вас появится достаточно знаний, чтобы сделать всё так, как захотите именно вы.
Начало смотрите здесь:
Первоначальная настройка сервера
Подготовка образа для загрузки по сети
Мы остановились на том, что загрузили по сети машину VirtualBox и запустили Firefox. Если сейчас попытаться сделать то же самое с настоящим компьютером, то на экране появится циклическая авторизация пользователя username и безуспешные попытки запустить графическое окружение — Xorg не находит нужный драйвер.
Запускаем видеокарты
Для работы графического режима в VirtualBox у нас установлено всё необходимое. Изначально планировалось, что наша бездисковая система будет функционировать на любом «железе», но из-за лени мы не станем пытаться объять необъятное, поэтому ограничимся поддержкой графических решений следующих доминирующих производителей: nVidia, Intel и AMD.
Переключимся на машине-клиенте во второй терминал нажатием Ctrl+Alt+F2 и установим открытые драйверы:
Вероятнее всего, что на этот раз Xorg не сможет самостоятельно выбрать подходящие настройки для каждого случая, и судя по экрану загруженного клиента будет казаться, что вообще ничего не изменилось.
Простейший способ узнать какие видеоустройства имеются в системе, это ввести в консоли команду:
Но мы не будем искать лёгких путей, а в награду получим новую порцию знаний.
Ближе знакомимся с udev
Раньше я уже упоминал, что менеджер устройств в Archlinux называется udev. Он входит в пакет systemd под именем systemd-udevd.
По мере обнаружения новых устройств в загружаемой системе, ядро создаёт их иерархию в каталоге /devices. Сначала появляется сама система PCI, затем в ней обнаруживаются шины, на которых «сидят» конечные устройства, а их драйверы рассортировывают устройства по классам. Устройства внутри классов обнаруживаются параллельно, точно как systemd параллельно запускает службы для достижения следующей цели.
Асинхронный поиск устройств приводит к тому, что если в компьютере одновременно присутствует несколько устройств, относящихся к одному классу, то они могут обнаруживаться в разном порядке от включения к включению, например, сначала одна видеокарта, а потом — другая, и их имена при этом будут меняться между собой. К счастью, появление нового элемента в иерархии устройств является событием udev, которое можно отследить и принять необходимые меры.
Для менеджера udev придуманы правила, призванные упорядочить хаос, и упростить жизнь установленных программ. Правила хранятся в папках /usr/lib/udev/rules.d/ и /etc/udev/rules.d/ (последняя, как и в случае обработчиков (hooks), имеет более высокий приоритет и файлы оттуда проверяются первыми). Появление нового элемента в иерархии устройств сопровождается проверкой всех установленных правил udev, и автоматическим выполнением указанных там действий, в случае совпадения. Обычно эти действия заключаются в переименовании устройств и установки на них ссылок в каталогах внутри /dev и /sys для удобства использования в программах.
Драйверы видеокарт относят их к подсистеме (классу) drm, поэтому сведения о подобных устройствах дублируются в каталоге /sys/class/drm. Первая видеокарта, обнаруженная в системе, по-умолчанию получает имя «card0», если в ней имеется несколько видеовыходов, то они получают имена вида «card0-CON-n», где «CON» — тип разъема (VGA, HDMI, DVI и др.), а «n» — порядковый номер разъема (причём одни производители нумеруют разъёмы начиная с «0», а другие — с «1»). Следующая видеокарта становится “card1” и т. д.
Если ничего не предпринять, то в виду параллельности обнаружения при следующем включении card1 может стать card0 и наоборот. Udev станет добавлять такие устройства в /dev то с одним, то с другим именем. Случаи, когда такое поведение udev нежелательно, подробно описаны в Интернете, и в них в основном обсуждаются различные USB устройства. Нам же требуется при обнаружении видеокарт запускать определённую программу, которую напишем чуть позже, а пока выясним, что известно udev.
Чтобы узнать то же самое, что знает про видеокарту udev, введём команду на клиенте:
Udevadm info starts with the device specified by the devpath and then
walks up the chain of parent devices. It prints for every device
found, all possible attributes in the udev rules key format.
A rule to match, can be composed by the attributes of the device
and the attributes from one single parent device.
looking at device ‘/devices/pci0000:00/0000:00:02.0/drm/card0’:
KERNEL==«card0»
SUBSYSTEM==«drm»
DRIVER==»»
looking at parent device ‘/devices/pci0000:00’:
KERNELS==«pci0000:00»
SUBSYSTEMS==»»
DRIVERS==»»
У родительского устройства /devices/pci0000:00/0000:00:02.0 есть атрибут vendor с идентификатором производителя. Udev располагает доступом к обширной базе данных и может перевести этот код в удобоваримый вид:
Сравните с выводом команды:
Динамическая настройка видеокарты с помощью udev
Подключитесь к загрузочному серверу. И создайте файл с правилами:
Правило из первой строки срабатывает для всех устройств с именем (ядром) card0, card1… подсистемы drm. Второе правило сработает только для активных устройств из подсистемы drm, к которым в данный момент подключен монитор (оно не сработает для card0, card1, а только для имен вида card0-HDMI-1, т. к. только у таких устройств есть атрибуты enabled и status). При совпадении события с его описанием выполняется одна и та же программа, в которую в первом случае передаётся один параметр %n (порядковый номер ядра, который для card0 будет «0»), а во втором — дополнительный параметр %k (само имя ядра «card0»).
Программа /etc/default/xdevice будет изменять содержимое файла в папке /etc/X11/xorg.conf.d/, в котором содержится информация о настройках видеоадаптера для xorg. Для разных производителей мы подготовим разные шаблоны, учитывающие особенности реализации. Достаточно указать минимально необходимую информацию для однозначной идентификации устройства, а остальное xorg сделает сам:
Необходимые данные мы укажем в самом шаблоне или получим исследуя вывод команды «udevadm info».
Программа будет срабатывать для каждого выхода каждой видеокарты, к которому подключен монитор. Для упрощения задачи заставим работать последний обнаруженный вариант, чтобы на мультимониторных системах работал хотя бы один монитор. Это не самый оптимальный способ настройки, и было бы лучше проверить графическую подсистему один раз перед достижением graphical.target, но наш вариантрабочий и подходит для изучения правил udev в действии.
Создаём файл программы со следующим содержанием:
Сделаем файл исполняемым:
Отключаем автоматическую загрузку службы VirtualBox, т. к. теперь она будет запускаться нашей программой только при необходимости:
Добавляем шаблоны конфигурационных файлов xorg, с оптимизированными под основных производителей настройками:
Добавляйте свои шаблоны и не забывайте устанавливать драйверы для этих устройств. Укажите в комментариях проверенные комбинации.
В завершение настройки xorg сделаем ”Windows like” переключение раскладки клавиатуры комбинацией Alt+Shift:
Оптимизируем систему
Логи работы всех составляющих Archlinux сохраняются в журнале. Если всё оставить как есть, то журнал может довольно сильно раздуть, поэтому ограничим его размер, скажем 30Мб (добавьте или раскомментируйте строку):
Каждое действие протоколируется в папку /var/log/journal. В нашем случае передача данных осуществляется по сети, которая на практике имеет невысокую пропускную способность. Можно удалить папку с журналом, то он будет сохраняться только в оперативной памяти, что идеально подходит для бездискового клиента:
При различных ошибках в работе приложений в папке /var/lib/systemd/coredump создаются автоматические дампы ядра. Мы их отключим по той же причине:
Удалим ненужные локализации. Это простое действие поможет сэкономить более 65 Мб. Заодно посмотрим, как устанавливаются программы из AUR (фактически они собираются из исходников). Зайдите на загрузочный сервер с правами обычного пользователя и выполните следующие действия:
Пакет готов. Устанавливаем его из файла, а не из репозитория, поэтому ключ S заменяется на U (исправьте название файла, если версия собранной вами програмы не совпадает с моей):
Теперь настроим. Закомментируйте строку «NEEDCONFIGFIRST» в начале файла и укажите используемые локализации в самом конце:
Конфигурируем и запускаем программу:
Переходим в read-only
Если мы попробуем загрузить существующую систему на нескольких компьютерах одновременно, то все копии будут изменять одни и те же папки на сервере. Если один клиент удалит какой-то файл, то он неожиданно исчезнет и у другого. Самый надежный способ защититься от изменений — перейти в режим только для чтения.
Проблема в том, что для нормальной работы системы необходима возможность записывать данные в некоторые папки. Решение на поверхности — подключить эти папки через fstab как tmpfs — замечательно подойдёт для /var/log, например. Но как поступить, например, с каталогом /etc, ведь наше правило udev меняет там файлы, да и другие программы активно с ним работают? Можно где-то сохранить информацию перед монтированием, а потом переписать обратно. Или сразу перенести всё куда-то ещё, а потом вернуть. Ясно одно: придётся долго тестировать и следить за работой системы, чтобы понять какие ещё папки сделать доступными для записи, или же настроить все программы так, чтобы они оставляли продукты своей жизнедеятельности строго в отведённом месте. Слишком мудрёно. Предлагаю всю систему развернуть в RAM. Останется только предварительно переписать в неё всё самое нужное для работы.
Существует одна папка, в которую во время работы ничего не записывается, если мы ничего не устанавливаем — это /usr. Если подмонтировать её на позднем этапе работы initramfs с доступом только для чтения, то на работу Firefox это никак не повлияет. Обязательно сравните размер каталога /usr с размером всего остального, и получится, что копировать останется не так много, а если при этом исключить всё лишнее… Вы тоже подумали о rsync?
Переделываем файловую систему на лету
Устанавливаем rsync на клиента:
Заниматься копированием предстоит на этапе работы intramfs, следовательно, понадобится новый обработчик, назовём его «live». Сначала сохраним все необходимые параметры монтирования оригинального корневого каталога, путём анализа файла /etc/fstab с помощью утилиты findmnt. Затем корневой каталог отмонтируем от папки /new_root, где он всегда находится внутри initramfs. На его месте создадим ramfs с возможностью записи и подготовим точку монтирования /srv/new_root, куда вернём оригинальный корневой каталог. Останется только переписать все самые нужные файлы и каталоги, за исключением папки /usr, которую забиндим в режиме только для чтения. Копии файлов в ramfs будут доступны для чтения и для записи.
К файлу /etc/fstab мы обращаемся дважды: первый раз получаем информацию по параметрам монтирования корневого каталога, а второй раз проверяем, есть ли в fstab какая-нибудь информация по /usr. Для позднего монтирования /usr в Archlinux есть специальный обработчик usr, которому мы не будем мешать выполнять свою работу. Если /usr монтируется каким-то особым образом, то наш обработчик его пропускает.
В тексте упомянут файл /etc/default/live_filter с правилами фильтрации, предназначенными для rsync, нам нужно не забыть его подготовить. Сделаем это автоматически из установщика обработчика:
Rsync «не видит» дальше одной директории. Файлы и папки в директории проверяются каждым правилом по порядку до первого совпадения («+» — объект копируется, «-» — объект не копируется). Если совпадений нет, то файл копируется, а директория создаётся пустой. Далее rsync заходит в «выжившую» директорию и снова применяет правила к её содержимому. Так повторяется до тех пор пока совсем ничего не останется.
Правила для rsync, находящиеся во внешнем файле /etc/default/live_filter, вы можете менять по своему усмотрению без необходимости заново создавать initramfs. Буду рад увидеть ваш вариант правил в комментариях.
Возможностей у rsync очень много (man rsync — почти 3000 строк). Предложите в комментариях какой-нибудь экзотический способ использования rsync внутри initramfs?
Теоретически rsync можно заменить на какой-нибудь torrent, и собирать корневую файловую систему с его помощью.
Добавляем обработчик в initramfs:
Сервер и клиент работают в VirtualBox.
Исходная файловая система:
Состояние файловой системы на загруженном клиенте после выполнения обработчика live:
Во время загрузки клиента на сервере были собраны следующие данные:
Разгоняем сеть
Физически, естественно, разгон сети сейчас невозможен без замены оборудования, зато программные оптимизации не запрещаются. Нам нужно передавать содержимое связанной папки /usr по сети. Не отправлять эти данные мы не можем, зато способны уменьшить объём занимаемого ими места — заархивировать. На сервере сжимаем, а на клиенте — распаковываем, и через ту же самую сеть теоретически передаётся больше данных за единицу времени.
Файловая система squashfs совмещает в себе возможности архиватора и монтирования архивов через fstab, как обычную файловую систему. Основной недостаток данной файловой системы — невозможность работать в режиме записи (только для чтения) — для нас недостатком не является:
Монтировать будем так:
На позднем этапе работы initramfs монтированием папки /usr занимается обработчик usr, который нужно немного подправить:
Нужно, чтобы строка монтирования выглядела так:
Исходная файловая система:
Состояние файловой системы на загруженном клиенте после выполнения обработчиков live и usr:
Во время загрузки клиента на сервере были собраны следующие данные:
Данных пришлось передать примерно на 20% меньше, чем в предыдущий раз. Можно упаковать весь корневой каталог в один файл, тогда обработчик live для заполнения ramfs будет забирать с сервера данные в сжатом виде.
Можно скопировать файл /srv/source_usr.sfs в ramfs поменяв правила в фильтре rsync, а потом примонтировать его через fstab из нового места, и, когда вся система целиком окажется в RAM, попробовать отключиться от загрузочного сервера.
Убираем лишнее
Если вы заглядывали сюда, то у вас не возникнет вопрос: «Как мы будем отдавать с сервера файл?». Можно, конечно, передавать данные squashfs посредством NFS (что и происходило выше), но существует менее документированное решение Network Block Device, с которым можно работать как с обычным диском. Поскольку это «блочное устройство», а не «файловая система», мы можем использовать на нём любую файловую систему с возможностью сжатия данных. Для доступа на чтение и запись подойдёт btrfs с архивацией zlib, но нам не нужна запись и squashfs вполне устраивает.
Чтобы из initramfs можно было подключиться к NBD-серверу при загрузке понадобится скачать из AUR пакет mkinitcpio-nbd (нужно скачивать и собирать с правами обычного пользователя):
Как видите, поменялась только одна строчка:
После подключения к NBD серверу в клиенте появляется блочное устройство с именем /dev/nbd0, поэтому поступаем с ним как с обычным диском:
В последних версиях NBD сервера появилась непрятная особенность (скорее всего это баг). Когда клиент NBD устанавливает соединение с сервером, а потом внезапно выключается не завершая соединение корректно, и оно продолжает «болтаться» на сервере в виде незавершенного процесса. Если клиент во время загрузки попробует подключиться к NBD заново, то есть вероятность, что сервер не станет создавать новое соедиенение считая старое активным. Предлагаю непосредственно перед подключением к NBD отправлять свой IP адрес через netcat на сервер, чтобы тот закрыл старые подключения, связанные с этим IP адресом:
Нужно отредактировать только один файл. Вставьте между строками следующий фрагмент:
В initramfs сетью по-прежнему заведует наш модифицированный net_nfs4, после которого вставляем nbd:
Переходим к настройке сервера
Настраиваем NBD сервер:
Всё достаточно просто. Мы создаём шару с именем habrahabr, ссылаемся на наш файл, устанавливаем таймаут соединения, раздаём в режиме «только для чтения», отдаём только один файл и функция copyonwrite нам не нужна. Copyonwrite позволяет использовать одну и ту же раздачу несколькими клиентами одновременно, при этом каждому клиенту создаётся отдельный файл, куда будут записываться все произведённые им изменения оригинального файла. После отключения клиента файлы с изменениями удаляются автоматически. Использование этой функции замедляет сервер. Информации по NBD в интернете не так много, но man’ы решают.
Проверять и завершать процессы, связанные с незакрытыми соединениями будет вот этот файл:
Файл делаем исполняемым:
Устанавливаем пакеты, в которых находятся утилиты netcat и netstat:
Модифицируем запуск службы NBD:
Возможно, выбрано не самое изящное решение, но оно достаточно понятно и замечательно работает.
Исходная файловая система:
Состояние файловой системы на загруженном клиенте после выполнения обработчиков live и usr:
Во время загрузки клиента на сервере были получены следующие данные:
На этот раз мы сэкономили ещё всего лишь 3% трафика (в пределах погрешности). Разница во времени загрузки объясняется тем, что при использовании NFS перед подключением к серверу делается принудительная пауза в 10 секунд, а в случае сервера NBD такой задержки нет.
Педаль в пол
Давайте попробуем ускорить загрузку. Самое слабое звено в нашей цепочке загрузки — TFTP сервер. Полностью исключить его мы не сможем, но минимизировать его присутствие можно с помощью загрузчика iPXE, как посоветовал kvaps в комментариях к предыдущей статье.
Подключитесь к загрузочному серверу под именем username.
Меню с вариантами загрузки мы делать не будем, а автоматически загрузимся в самый быстрый на текущий момент:
Мы планируем получать файлы vmlinuz-linux и initramfs по протоколу HTTP. Внедрим наш скрипт в загрузчик:
Возвращаемся в root на сервере и копируем загрузчик:
Исправим DHCP сервер таким образом, чтобы он предлагал скачивать новый файл:
Устанавливаем HTTP сервер:
привязываем папку с загрузчиком к рабочей папки сервера:
Можно перемонтировать в режим «только для чтения»:
Смотрим, что происходит на сервере:
Выигрыш в скорости загрузки от замены TFTP на HTTP заметен невооружённым глазом и это не единственный примечательный момент iPXE. Например, здесь показано, как можно прямо во время загрузки выбрать сервер с официальным образом установочной флешки и загрузиться в него прямо через Интернет без необходимости предварительного скачивания. Уверен, что теперь вы сможете повторить то же самое и со своим образом.
Возвращаемся на сервер
Попробуйте добавить обработчик live в наш загрузочный сервер. Сейчас правила rsync пропускают копирование содержимого /srv, где у нас находятся файлы клиента. Мы можем поменять правила или примонтировать директорию с помощью systemd:
В данном случае папки /srv/new_root/srv и /srv связываются в режиме полного доступа на чтение и запись, но мы знаем решения.
Тот факт, что загрузочный сервер может работать в режиме «только для чтения», будет весьма полезен для систем, установленных на недорогую USB флешку. С такого накопителя лучше побольше читать, и поменьше на него записывать. Если вы откроете его в интернет, то получите дополнительную степень защиты. Например, роутер открывает защищенный VPN канал, на другом конце которого находится загрузочный сервер…
Чтобы переписать систему на флешку (с жёстким диском принцип тот же самый), её нужно вставить в компьютер и подключить к VirtualBox (Меню Устройства > Устройства USB и выбрать нужную из списка). Список доступных блочных устройств проверяется командой lsblk, как в самой первой статье. Разметьте флешку пометив загрузочной, отформатируйте с той же меткой HABR и примонтируйте к /mnt.
Создадим новый файл с правилами для rsync:
Дождитесь выполнения команды:
В моём случае флешка — /dev/sdb
Остаётся отмонтировать /mnt и можно загружаться из копии.
PS Решение разрабатывалось для автоматизации компьютерных классов. Система одинаково работает на пожертвованных и новых компьютерах с самыми разнообразными конфигурациями. Восстановление системы на клиенте к первоначальному состоянию производится обычной перезагрузкой. Нужные данные можно сохранять на диске загрузочного сервера или на любом другом сетевом или локальном накопителе.