From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Date: Thu, 17 May 2012 08:19:46 +0400 From: Alexey Tourbin To: devel@lists.altlinux.org Message-ID: <20120517041945.GA29972@altlinux.org> Mime-Version: 1.0 Content-Type: text/plain; charset=koi8-r Content-Disposition: inline Content-Transfer-Encoding: 8bit X-Mailman-Approved-At: Thu, 17 May 2012 14:34:18 +0400 Subject: [devel] atime-based "no need to rebuild" X-BeenThere: devel@lists.altlinux.org X-Mailman-Version: 2.1.12 Precedence: list Reply-To: ALT Linux Team development discussions List-Id: ALT Linux Team development discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 17 May 2012 04:19:47 -0000 Archived-At: List-Archive: List-Post: Мужчины, у вас медленно задания собираются. Потому что при повторном запуске выполняется пересборка всех пакетов, а оптимизация "no need to rebuild" срабатывает только при очень строгом условии: список пакетов в чруте должен быть полностью идентичным, с точностью до конкретной сборки каждого пакета (пересобранный пакет уже не идентичен). Далее я обсуждаю другие критерии для повторной пересборки и как их можно использовать для дальнейшей оптимизации. Есть два основных аспекта этой проблемы. 1) После повторной пересборки в пакете появляются новые значения st_mtime, основанные на текущем времени; это в свою очередь запускает каскад пересборок, даже если содержимое файлов в пакете не меняется. Следовательно, чтобы остановить этот каскад, в качестве критерия пересборки нужно учитывать только содержимое файлов (md5 суммы). 2) Некоторые пакеты во время сборки просто не используются. Например, пакет cpio редко используется при сборке, но он входит в базовую сборочную среду; его обновление запустит лишнюю пересборку какого бы то ни было пакета. Такие ситуации возникают и за пределами базовой сборочной среды. Следовательно, в качестве критерия пересборки нужно учитывать только фактически используемые пакеты. Исходя из этих соображений я реализовал альтернативный/дополнительный критерий, который учитывает использование файлов в чруте. В двух словах, он работает так: при первой сборке отслеживаются фактически используемые файлы (на основе разницы между st_mtime/st_ctime и st_atime). Перед началом повторной сборки используемые файлы проверяются: если они совпадают (с точностью до md5 сумм), то пересборка не требуется. http://git.altlinux.org/people/at/packages/girar-builder.git Несколько точнее, перед самым началом сборки, когда все пакеты BuildRequires уже установлены, запускается специальная программа, которая "сбрасывает" st_atime у всех файлов в чруте. Эту программу пришлось написать на Си, потому что там есть тонкости. Сбрасывать st_atime требуется, чтобы он обновлялся на файловых системах, смонтированных с опцией relatime (которая используется по умолчанию). Затем запускается сборка, и после ее завершения запускается другая программа, которая ищет в чруте все "использованные" файлы (у которых st_atime > st_mtime/ctime). Эта схема отслеживания достаточно надежна, поскольку псевдопользователь builder не может изменить атрибуты запакованных файлов, принадлежащих псевдопользователю rooter. Некоторые файлы отслеживать не нужно. Например, в базе /var/lib/rpm/ содержатся значения st_mtime всех файлов, которые как бы дублируют значения st_mtime в реальной файловой системе (от которых мы как раз пытаемся избавиться). В /var/cache/ldconfig/ содержатся значения st_ctime библиотек. В /etc/passwd содержатся численные идентификаторы псевдопользователей rooter и builder, которые отличаются на сборочных нодах. Самое спорное решение - не отслеживать файлы в /usr/share/doc/. Я обосную его чуть ниже. Список использованных файлов не может быть исчерпывающим критерием. Например, при первой сборке в чруте может отсутствовать библиотека foo. Скрипт configure скажет "checking for libfoo... no", т.е. программа соберется в конфигурации без libfoo. Если для повторной сборки установить в чрут libfoo-devel, то ранее использованные файлы могут быть полностью идентичны, но результат сборки изменится, поскольку в чруте появились новые файлы. Следовательно, полный критерий должен учитывать все файлы в чруте, но для неиспользуемых файлов нужно учитывать только имя (без md5 суммы). Теперь становится понятно, почему я предлагаю не отслеживать содержимое /usr/share/doc/: каталоги в /usr/share/doc/ традиционно включают в себя версию пакета, т.е. при сборке новой версии какого-либо пакета будет срабатывать критерий изменения списка неиспользуемых файлов. Если вернуться к примеру с cpio, это выглядит нежелательно. Наконец, остается вопрос: нужно ли учитывать симлинки? С одной стороны, симлинки не содержат самостоятельных данных. С другой стороны, легко придумать контрпример: если симлинк 'gcc -> gcc4.5' заменить на 'gcc -> gcc4.6', то результат сборки может серьезно измениться. Короче, симлинки "перекраивают" файловую систему, и их можно рассматривать как миниатюрные конфигурационные файлы. Пути симлинков учитываются наравне с md5 суммами файлов. Эти изменения привносит несколько новых файлов в задание: кроме chroot_base и chroot_BR (списки пакетов), в каждом каталоге появятся файлы chroot_fused и chroot_funused (списки использованных и неиспользованных файлов). Кроме того, если выполняется повторная сборка, то добавляются файлы chroot_pdiff и chroot_fdiff, из которых можно понять причину пересборки. Насколько было возможно, я протестировал эти изменения.