This is Gentoo's testing wiki. It is a non-operational environment and its textual content is outdated.
Please visit our production wiki at https://wiki.gentoo.org
Distcc
Distcc — это программа, предназначенная для распределения по сети задач компиляции в рамках набора хостов. Она состоит из серверной части — distccd и клиентской — distcc. После небольшой настройки distcc может прозрачно работать с ccache, Portage и с небольшой настройкой Automake.
Если планируется использовать distcc для начальной сборки (bootstrap) установки Gentoo, обратите внимание на раздел использование distcc для bootstrap.
Установка
Перед настройкой distcc сперва нужно установить пакет sys-devel/distcc на все хосты.
Требования для всех хостов
Для работы с distcc все компьютеры в сети должны иметь GCC одной версии. К примеру, можно использовать на разных машинах 3.3.x (где x — разные), а смешивание 3.3.x с 3.2.x может привести к ошибкам при компиляции или выполнении.
USE-флаги
USE flags for sys-devel/distcc Distribute compilation of C code across several machines on a network
gssapi
|
Enable support for net-libs/libgssglue |
gtk
|
Add support for x11-libs/gtk+ (The GIMP Toolkit) |
hardened
|
Activate default security enhancements for toolchain (gcc, glibc, binutils) |
ipv6
|
Add support for IP version 6 |
selinux
|
!!internal use only!! Security Enhanced Linux support, this must be set by the selinux profile or breakage will occur |
xinetd
|
Add support for the xinetd super-server |
zeroconf
|
Support for DNS Service Discovery (DNS-SD) |
Emerge
Distcc поставляется с графическим монитором для отслеживания заданий, отправляемых компьютером на компиляцию. Данный монитор включается, когда установлен USE-флаг gtk
.
После настройки USE-флагов установите пакет sys-devel/distcc:
root #
emerge --ask sys-devel/distcc
Убедитесь, что sys-devel/distcc установлен на все участвующие в распределённой компиляции компьютеры.
Конфигурация
Сервис
Выполните следующие инструкции для того чтобы distccd запускался автоматически.
OpenRC
Отредактируйте /etc/conf.d/distccd и убедитесь, что с помощью директивы --allow
разрешены только доверенные клиенты. Для усиления безопасности можно также добавить директиву --listen
, сообщив с её помощью демону distccd, на каком IP ожидать соединений (для систем с несколькими адресами). Подробнее о безопасности в distcc можно почитать в Distcc security notes.
Следующий пример разрешает distcc клиентам, работающим на 192.168.0.4
и 192.168.0.5
, подключатся к локально запущенному серверу distccd:
DISTCCD_OPTS="--port 3632 --log-level notice --log-file /var/log/distccd.log -N 15 --allow 192.168.0.4 --allow 192.168.0.5"
Использовать
--allow
и --listen
— важно. Обратитесь к man-странице distccd или указанному выше документу по безопасности для получения дополнительной информации.Теперь запустите демон distccd на всех участвующих компьютерах:
root #
rc-update add distccd default
root #
rc-service distccd start
systemd
Отредактируйте файл /etc/systemd/system/distccd.service.d/00gentoo.conf для добавления доверенных клиентов в CIDR формате. Пример ниже добавляет все IP-адреса из диапазона 192.168.1.xxx:
Environment="ALLOWED_SERVERS=192.168.1.0/24"
Имя "ALLOWED_SERVERS" сильно запутывает, так как на самом деле оно относится к клиентам, которым разрешено подключаться к локальному серверу distcc. Тем не менее именно эта переменная используется в сервисе distccd как значение для
--allow option
. Смотрите файл /usr/lib/systemd/system/distccd.service для более подробной информации.Перезагрузите unit-файлы после изменений:
root #
systemctl daemon-reload
Включите автозагрузку distccd и запустите сервис:
root #
systemctl enable distccd
root #
systemctl start distccd
Определение участвующих хостов
Для задания списка хостов используйте команду distcc-config.
В следующем примере показан список определения хостов. Вариантов из первой и второй строки в большинстве случаев достаточно. В последнем используется (число) /limit
синтаксис, чтобы сообщить distcc о максимально возможном количестве задач, которые можно запустить на этом узле. Подробнее о синтаксисе, использованном в третьей и четвертой строках, можно прочитать в man-странице distcc.
192.168.0.1 192.168.0.2 192.168.0.3 192.168.0.1/2 192.168.0.2 192.168.0.3/10 192.168.0.1:4000/2 192.168.0.2/1 192.168.0.3:3632/4 @192.168.0.1 @192.168.0.2:/usr/bin/distccd 192.168.0.3
Есть также несколько других методов для настройки хостов. За подробностями обратитесь к distcc man-странице man distcc.
Если локальная машина должна участвовать в компиляции, поместите localhost
в список хостов. Наоборот, если локальная машина не должна участвовать в компиляции, не включайте её в список хостов. Использование localhost на медленной машине может, как ни странно, замедлить процесс. Всегда проверяйте влияние настроек на производительность.
Настроим distcc для компиляции на хостах из первой строчки примера:
root #
/usr/bin/distcc-config --set-hosts "192.168.0.1 192.168.0.2 192.168.0.3"
Также, distcc поддерживает режим "pump" через вызов команды pump. Такой режим может значительно сократить время сборки при компиляции нескольких файлов параллельно. Он кэширует нужные заголовочные файлы перед компиляцией на сервере, и, как следствие, не требуется повторная загрузка и обработка этих файлов.
Чтобы настроить хост для работы в режиме pump, добавьте суффикс ,cpp,lzo
в определение хостов. Для режим pump необходимы оба флага cpp
и lzo
(независимо от того, какие файлы будут компилироваться C или C++).
root #
/usr/bin/distcc-config --set-hosts "192.168.0.1,cpp,lzo 192.168.0.2,cpp,lzo 192.168.0.3,cpp,lzo"
Использование
С Portage
Весьма легко настроить Portage для работы с distcc. Речь идет о включении функции distcc, а также о настройки подходящего количества одновременно выполняемых задач (так как distcc увеличивает доступное количество ресурсов для компиляции).
Установите переменные MAKEOPTS и FEATURES как показано ниже.
Общепринятая стратегия
- установите
N
в удвоенное значение от всех (локальных + удалённых) ядер CPU + 1, - установите
M
число равное количеству локальных ядер CPU.
Использование -lM
в переменной MAKEOPTS предотвращает запуск чрезмерно большого количества заданий в случаях, когда некоторые distcc хосты кластера недоступны (увеличивая количество одновременных заданий для других систем) или когда ebuild настроен так, что устанавливаемый пакет запрещает удаленную компиляцию (например, gcc). Это достигается за счет отказа начинать новые задачи компиляции, если нагрузка на систему становится равной M
или выше.
# Замените N и M на подходящие значения, как писалось ранее в статье MAKEOPTS="-jN -lM" FEATURES="distcc distcc-pump"
Установка значения
network-sandbox
в переменной FEATURES на клиенте, по видимому, не позволяет клиенту передавать данные компиляции на другие сервера, так как это значение блокирует сетевое взаимодействие. Убедитесь, что это значение не установлено (отсутствует) или отключено (-network-sandbox
).Режим pump в distcc может сильно сократить время сборки для больших пакетов. Более подробную информацию смотрите в разделе определение участвующих хостов.
Например, если distccd запущен на двух четырехъядерных хостах, а локальный компьютер оснащен двухъядерным процессором, то переменная MAKEOPTS может выглядеть так:
# 2 удалённых хоста с 4 ядрами каждый = 8 удалённых ядер # 1 локальный хост с двумя ядрами = 2 локальных ядра # общее количество ядер — 10, N = 2*10+1 и M=2 MAKEOPTS="-j21 -l2"
CFLAGS и CXXFLAGS
Не используйте -march=native
в переменных CFLAGS и CXXFLAGS файла make.conf. Если march установлен в native
, то distccd не сможет распределить работу по другим машинам. Подходящее значение для march
можно получить с помощью следующей команды:
user $
gcc -v -E -x c -march=native -mtune=native - < /dev/null 2>&1 | grep cc1 | perl -pe 's/^.* - //g;'
Подробности можно найти на странице Inlining -march=native
for distcc.
A GCC bug has recently been fixed in the 8.0 dev tree which facilitates a more reliable and succinct mechanism for extrapolating appropriate machine flags. The fix has been backported to the 6 and 7 branches and should be released fairly soon. Some processing is still required and a script can be found in the distccflags repo, or via wget:
Скачивание и запуск скриптов без какой-либо проверки - угроза безопасности системы. Прежде чем запускать скрипт, выясните, что он делает, и воздержитесь от запуска если содержимое или поведение вам неясно.
user $
chmod +x distccflags
user $
./distccflags -march=native
С automake
Иногда это проще настройки Portage. Всё, что нужно сделать, это обновить переменную PATH, добавив /usr/lib/distcc/bin/ перед каталогом, содержащим gcc (/usr/bin/). С одной оговоркой. Если используется ccache, то нужно поместить путь к distcc после пути к ccache:
root #
export PATH="/usr/lib/ccache/bin:/usr/lib/distcc/bin:${PATH}"
Поместите это в пользовательский ~/.bashrc или его эквивалент, чтобы переменная PATH устанавливалась при каждом входе пользователя в систему, либо задайте ее глобально через файл /etc/env.d/.
Вместо вызов одного make, добавьте -jN
(где N — целое число). Значение N
зависит от сети и используемых для компиляции компьютеров. Эвристический подход к определению правильного значения N
упоминался ранее в этой статье.
Для bootstrap
Для использования distcc для bootstrap (то есть скомпилировать рабочие toolchain перед установкой оставшейся части системы) требуются некоторые дополнительные шаги.
Шаг 1: настройка Portage
Загрузите новую машину с Gentoo Linux LiveCD и следуйте инструкциям по установке, учитывая инструкции по начальной сборке (bootstrapping) в FAQ по Gentoo. Затем настройте Portage для использования distcc:
FEATURES="distcc" MAKEOPTS="-jN"
Также, обновите переменную PATH в установочной сессии:
root #
export PATH="/usr/lib/ccache/bin:/usr/lib/distcc/bin:${PATH}"
Шаг 2: установка distcc
Установите sys-devel/distcc:
root #
USE='-*' emerge --nodeps sys-devel/distcc
Шаг 3: настройка distcc
Запустите distcc-config --install для настройки distcc; замените в примере host#
на IP-адреса или имена хостов, принимающих участие в компиляции.
root #
/usr/bin/distcc-config --set-hosts "localhost host1 host2 host3 ..."
Distcc теперь настроен для bootstrap! Продолжайте следовать соответствующим инструкциям по установке и не забудьте запустить emerge distcc после запуска emerge @system. Это нужно, чтобы убедиться, что все необходимые зависимости установлены.
В процессе начальной установки (bootstraping’а) и выполнения emerge @system distcc может не использоваться. Это ожидаемое поведение: некоторые файлы ebuild плохо работают с distcc, поэтому distcc отключён в них преднамеренно.
Дополнительно
У программы distcc есть множество дополнительных возможностей и приложений, помогающих работать в окружении distcc.
Утилиты для мониторинга
Distcc поставляется с двумя инструментами мониторинга. Текстовая утилита для мониторинга собирается всегда и называется distccmon-text. Интерфейс поначалу может смутить, но на самом деле использовать его очень просто. Если запустить программу без параметров, она просто запустится однократно. Однако, если передать ей в качестве параметра число N
, то информация будет обновляться каждые N
секунд.
user $
distccmon-text 10
Другая утилита для мониторинга включается с помощью USE-флага gtk
. Она основана на GTK+, запускается в окружении X и достаточно приятна. В Gentoo, чтобы избежать путаницы, GUI-монитор переименован в distccmon-gui (оригинальное название — distccmon-gnome).
user $
distccmon-gui
Чтобы наблюдать за тем, как Portage использует distcc, запустите:
root #
DISTCC_DIR="/var/tmp/portage/.distcc/" distccmon-text 10
root #
DISTCC_DIR="/var/tmp/portage/.distcc/" distccmon-gui
Если каталог distcc находится где-нибудь в другом месте, измените переменную DISTCC_DIR соответствующим образом.
Трюк: задайте DISTCC_DIR в переменном окружении:
root #
echo 'DISTCC_DIR="/var/tmp/portage/.distcc/"' >> /etc/env.d/02distcc
Теперь, обновите окружение:
root #
env-update
root #
source /etc/profile
И наконец, запустите графическую оболочку приложения:
root #
distccmon-gui
SSH для взаимодействия
В настройке distcc через SSH есть подводные камни. Во-первых, сгенерируйте ключевую пару SSH без пароля. Учтите, что Portage компилирует программы из-под пользователя portage (по умолчанию как root, если не включена FEATURES="userpriv"
). Домашний каталог пользователя portage — /var/tmp/portage/, поэтому ключи должны храниться в /var/tmp/portage/.ssh/.
root #
ssh-keygen -b 2048 -t rsa -f /var/tmp/portage/.ssh/id_rsa
Во-вторых, сделайте для каждого хоста раздел в файле конфигурации SSH:
Host test1 HostName 123.456.789.1 Port 1234 User UserName Host test2 HostName 123.456.789.2 Port 1234 User UserName
Отправьте публичный ключ на все ноды, участвующие в компиляции:
root #
ssh-copy-id -i /var/tmp/portage/.ssh/id_rsa.pub UserName@CompilationNode
Убедитесь также, что каждый из хостов есть в файле known_hosts:
root #
ssh-keyscan -t rsa <compilation-node-1> <compilation-node-2> [...] > /var/tmp/portage/.ssh/known_hosts
Измените владельца так:
root #
chown -R portage:portage /var/tmp/portage/.ssh/
Чтобы настроить хосты test1
и test2
, выполните:
root #
/usr/bin/distcc-config --set-hosts "@test1 @test2"
Обратите внимание на знак @
, с его помощью в distcc указываются ssh-хосты.
Наконец, сообщите distcc какой бинарный файл SSH нужно использовать:
DISTCC_SSH="ssh"
Если взаимосвязь distcc осуществляется через SSH, нет нужды запускать distccd init-скрипт на хостах.
Тестирование
Чтобы протестировать работу distcc напишите простую Hello distcc программу и запустите distcc в подробном режиме (verbose), чтобы убедится, что взаимосвязь между хостами distcc работает хорошо.
#include <stdio.h> int main() { printf("Hello distcc!\n"); return 0; }
Далее, включите подробный режим, скомпилируйте программу с помощью distcc и слинкуйте сгенерированный объектный файл в исполняемый:
user $
export DISTCC_VERBOSE=1
user $
distcc gcc -c main.c -o main.o # or 'pump distcc <...>'
user $
gcc main.o -o main
Замените команду distcc на команду pump distcc, чтобы использовать режим pump.
There should be a bunch of output about distcc finding its configuration, selecting the host to connect to, starting to connect to it, and ultimately compile main.c. If the output does not list the desired distcc hosts, check the configuration.
Наконец, проверьте, что скомпилированная программа работает хорошо. Чтобы протестировать все хосты, перечислите все хотсы компиляции в файле hosts.
user $
./main
Hello distcc!
Устранение проблем
Следующий раздел может помочь в решении проблем, если такие встречаются при использовании distcc.
ERROR: failed to open /var/log/distccd.log
По состоянию на 22 января 2015 года файл distccd.log в /var/log/ не правильно создается. По-видимому это затрагивает только версию 3.1-r8 distcc. Эта ошибка еще решается (смотрите bug #477630). Ее можно решить самостоятельно, создав файл журнала и назначив ему правильного владельца. После этого перезапустите демон distccd:
root #
mkdir -p /var/log/distcc
root #
touch /var/log/distcc/distccd.log
root #
chown distcc:daemon /var/log/distcc/distccd.log
Затем, в конфигурационном файле distccd, который располагается в /etc/conf.d/distccd, измените /var/log на каталог distcc, который был создан ранее:
DISTCCD_OPTS="--port 3632 --log-level notice --log-file /var/log/distcc/distccd.log -N 15
Наконец, перезапустите сервис distccd:
root #
/etc/init.d/distccd restart
Некоторые пакеты не используют distcc
Можно заметить, что сборка некоторых пакетов не распределяется по хостам (и не происходит параллельно, т. е. в несколько процессов). Такое может происходить, когда Makefile пакета не поддерживает параллельные операции, или мейнтейнер ebuild’а явно отключил их, чтобы избежать известных проблем.
Иногда distcc может вызывать сбой при компиляции пакета. Если такое происходит, пожалуйста, сообщите об этом.
Смешанные версии GCC
Если на взаимодействующих хостах разные версии GCC, то велика вероятность возникновения очень странных проблем. Решение — установить на все хосты одну версию GCC.
После недавных обновлений Portage стал использовать ${CHOST}-gcc
(минус gcc) вместо gcc
. Это значит, что совместное использование i686-машин с машинами других типов (i386, i586) может вызвать проблемы со сборкой. Обходным решеним может быть запуск:
root #
export CC='gcc' CXX='c++'
Можно задать переменные CC и CXX в /etc/portage/make.conf в списком значений из команды выше.
Так вы явно переопределите некоторую часть поведения Portage, что может привести к странным результатам в будущем. Делайте так, только если использование разных CHOST’ов неизбежно.
Просто установленной в слот подходящей версии gcc недостаточно. Portage использует distcc как замену для компилятора, который обозначен в переменной CHOST (например
x86_64-pc-linux-gnu
), а distccd вызывает его точно с таким же именем. Правильная версия gcc должна быть установлена в качестве системного компилятора на всех хостах, используемых для компиляции.-march=native
GCC, начиная с версии 4.3.0, поддерживает параметр -march=native
, который включает автоматическое определение CPU, на котором запущен GCC, и оптимизаций, которые стоит включить для него. Это создает проблемы при использовании distcc, так как допускает смешивание оптимизированного для разных процессоров кода. К примеру, запуск distcc с -march=native
на системе с процессором AMD Athlon и на другой системе с процессором Intel Pentium приведет к смешиванию кода, скомпилированного на обоих процессорах.
Обратите внимание на следующее предупреждение:
Не используйте
-march=native
и -mtune=native
в переменных CFLAGS и CXXFLAGS файла make.conf при компиляции с помощью distcc.Посмотрите раздел CFLAGS и CXXFLAGS и использование -march=native
в distcc для подробной информации.
Получение более подробного вывода в логах emerge
Можно получить более подробное журналирование, если включить подробный режим. Этого можно добиться, если добавить DISTCC_VERBOSE в /etc/portage/bashrc:
export DISTCC_VERBOSE=1
Подробный журнал потом можно найти в /var/tmp/portage/$CATEGORY/$PF/temp/build.log.
Keep in mind that the first distcc invocation visible in build.log isn’t necessary the first distcc call during a build process. For example a build server can get a one-minute backoff period during the configuration stage when some checks are performed using a compiler (distcc sets a backoff period when compilation on a remote server failed, it doesn’t matter whether it failed on local machine or not).
Поищите в каталоге /var/tmp/portage/$CATEGORY/$PF/work/, что изучить такую ситуацию. Найдите другие журналы или вызовите make непосредственно из рабочего каталога.
DISTCC_SAVE_TEMPS — это еще одна интересная переменная. Когда она установлена, сохраняется стандартный поток вывода/ошибок с удаленного компилятора, который использует Portage, в файлы расположенные в каталоге /var/tmp/portage/$CATEGORY/$PF/temp/.
export DISTCC_SAVE_TEMPS=1
Смотрите также
- Руководство по кросс-компиляции с distcc расскажет как компилировать программу на компьютере одной архитектуры для выполнения ее на другой архитектуре при помощи distcc. Это может быть так же просто, как компилировать на Athlon (i686) для выполнения на K6-2 (i586), или компилировать на SPARC для выполнения программы на PowerPC.
Внешние ресурсы
This page is based on a document formerly found on our main website gentoo.org.
The following people contributed to the original document: Lisa Seelye, Mike Gilbert (floppym), Erwin, Sven Vermeulen (SwifT), Lars Weiler, Tiemo Kieft, and Joshua Saddler (nightmorph)
They are listed here because wiki history does not allow for any external attribution. If you edit the wiki article, please do not add yourself here; your contributions are recorded on each article's associated history page.