Содержание
- Ошибки сборки пакетов RPM
- Содержание
- error: Installed (but unpackaged) file(s) found
- File not found
- cp: cannot stat ‘ ‘: No such file or directory
- Reversed (or previously applied) patch detected
- /var/tmp/rpm-tmp.xxxxx: line yy: cd: : No such file or directory
- empty-debug-info и debuginfo-without-sources
- Error: Can’t locate Some/Perl/Module.pm in @INC
- Package(s) suggested but not available
- ERROR: dependency(ies) not available
- hunk FAILED — saving rejects
- package ‘foo’ not found
- «No package ‘.*’ found»
- /usr/bin/ld: cannot find -lfoo
- Build.PL: No such file or directory
- Makefile.PL: No such file or directory
- fg: no job control
- Package check «/usr/bin/rpmlint . » failed
Ошибки сборки пакетов RPM
В данной статье мы собрали несколько часто встречающихся при сборке пакетов RPM ошибок подобного рода и способы их исправления. Этот перечень создан на основе опыта прохождения практики студентами НИУ ВШЭ, но мы надеемся, что он пригодится не только им.
При сборке новых версий программ с помощью Updates Builder подобные ошибки исправляются автоматически (скриптом analyze_log.sh), так что можно использовать код этого скрипта как подсказку — что надо делать. Впрочем, скрипт не универсален и может не работать в каких-то специфических случаях.
Содержание
error: Installed (but unpackaged) file(s) found
Ошибка означает, что в новой версии пакета появились новые файлы, отсутствующие ранее, и rpmbuild не знает, что с ними делать (и нужны ли ли вообще).
Если вы полагаете, что эти файлы нужны (а это так в 99.9% случаев), необходимо добавить их в секцию %files spec-файла. Если у вас есть несколько подпакетов, то надо сначала определить — к какому из них эти файлы относятся. Универсального рецепта здесь нет, однако есть несколько правил:
- файлы в директориях /usr/include , /ust/lib(64)/pkgconfig , добавляются в devel-пакеты
- файлы библиотек в директориях /lib(64) и /usr/lib(64) , оканчивающиеся на суффикс .so (например, libfoo.so ), также добавляются в devel-пакеты
- файлы библиотек в директориях /lib(64) и /usr/lib(64) , оканчивающиеся на цифру (например, libfoo.so.1 ), добавляются в пакеты с соответсвующими библиотеками. Согласно правилам РОСЫ, каждая библиотека должна упаковываться в отдельный подпакет, соотевтсвующий ее имени и значению SONAME (как правило, это цифра после суффикса .so — так что файлы libfoo.so.1 и libfoo.so.1.2 должны находиться в пакете lib(64)foo1 ). Часто ошибка «Installed but unpackaged files found) в пакетах с библиотеками вызвана изменением значения SONAME — например, вместо libfoo.so.1 в новой версии пакета появился файл libfoo.so.2 . В этом случае вы также дополнительно увидите ошибку «Cannot find file or directory», сообщающую, что отсутсвует файл libfoo.so.1 . Для исправления сборки в такой ситуации достаточно изменить значение макроса major в начале spec-файла:
Помните, что при добавлении файлов в секции %files принято заменять некоторые стандартные пути макросами (например вместо /usr/lib и /usr/lib64 необходимо использовать макрос %<_libdir >, вместо /usr/share/man — % <_mandir >и так далее). Более полный список можно посмотреть с скрипте из Updates Builder.
File not found
Ошибка означает, что в новой версии пакета отсутсвуют некоторые файлы, присутствувавшие ранее. Причин для этого может быть несколько:
- в новой версии действительно нет таких файлов — в этом случае надо просто убрать их описание из секции %files
- в новой версии файлы переименованы либо перемещены в другое место. В этом случае вы также увидите ошибку «Installed (but unpackaged) file(s) found», как в случае с библиотеками (см. выше). В случае с библиотеками для исправления сразу обеих ошибок необходимо изменить значение переменной major в начале spec-файла. В общем же случае необходимо исправить секцию %files , чтобы она соответсвовала новым реалиям.
- отсутсвующие файлы собираются или не собираются в зависимости от параметров окружения и сборки — опций компиляции или установленных в сборочной среде пакетов (описанных в BuildRequires). Возможно, в новой версии пакета надо использовать какие-то новые опции сборки либо добавить дополнительные сборочные зависимости для получения этих файлов. Выявить такие ситуации можно на основе анализа журналов сборки и вывода команд наподобие configure или cmake, которые сообщают, какие опцилнальные возможности будут включены при сборке, а какие — нет. Например, squid может собираться с поддержкой аутентификации SASL и без нее. В первом случае в пакете будет присутсвовать файл basic_sasl_auth, во втором его не будет. Для ключения/отключения SASL необходимо добавить/удалить значение SASL из параметра —enable-auth-basic команды configure , а также добавить сборочную зависимость (BuildRequires) от sasl-devel .
Помните, что при добавлении файлов в секции %files принято заменять некоторые стандартные пути макросами, а также что при описании файлов в секции %files могут использоваться символы ‘?’ и ‘*’ (означающие один произвольный символ и любое количество произвольных символов соответсвенно).
cp: cannot stat ‘ ‘: No such file or directory
Ошибка означает, что rpmbuild не смог найти файл , помеченный как %doc в секции %files вашего пакета. Возможно, этот файл был переименован (в этом случе вы также увидите ошибку «Installed (but unpackaged) file(s) found») — в этом случае надо изменить имя файла на новое (например, README могут переименовать в README.md ). Если неупакованного файла с близким именем не появилось, то значит старый файл в новой версии отсутсвует и его определение в %doc необходимо просто удалить.
Reversed (or previously applied) patch detected
Ошибка означает, что применявшийся к старой версии пакета патч по крайней мере частично уже применен в новой версии. Обратите внимание, что команда patch делает такой вывод на основе попытки применить только первую часть патча! Если патч сложный и затрагивает несколько файлов или несколько мест одного файла, то необходимо вручную проверить, какие из этих изменений уже есть в новой версии, а каких нет. Для этого можно попробовать применить патч к новой версии вручную, отвечая «n» на вопрос «Assume ‘-R’» и «y» на предложени продолжить применять остальные части патча.
Если все изменения из патча действительно уже присутсвуют в новой версии, то патч можно спокойно удалить (физически из Git-репозитория, а также из spec-файла). Если же нет, то необходимо определить — нужны ли в новой версии оставшиеся изменения и если да, то переделать патч соответствующим образом. Такой анализ уже требует некоторых познаний в том, что именно делает патч.
/var/tmp/rpm-tmp.xxxxx: line yy: cd: : No such file or directory
Ошибка означает, что rpmbuild не может определить, в какую директорию ему перейти после распаковки архива с исходным кодом. Имя директории указывается в опции -n макроса %setup в секции %prep . Если эта опция отсутсвует, то подразумевается использование «-n %-%«. Для исправления ошибки необходимо посмотреть, как расположены файлы в новой версии архива с исходным кодом — обычно такой архив содержит директорию вида » — «, но время от времени разработчики могут что-то изменять (например, переименовывать директорию просто в . Для исправления ошибки необходимо соответсвующим образом исправить значение опции «-n» макроса %setup .
empty-debug-info и debuginfo-without-sources
Ошибки означают, что rpmbuild не смог должным образом сформировать подпакет с отладочной информацией. Две основные причины такого поведения:
- в пакете нет исполнимых файлов или библиотек. Если в пакете при этом вообще нет архитектурно-зависимых файлов (т.е. пакеты для разных архитектур имею абсолютно одинаковое содержимое), то необходимо объявить пакет как независимый от архитектуры, добавив в заголовок spec-файла декларацию «BuildArch: noarch». Если же архитектурно-зависимые файлы все-таки есть (например, какие-то данные могут быть специфичны для каждой арзитектуры; другой типичный пример — проприетарное приложение, которое уже поставляется в виде бинарных файлов бех отладочной информации), то необходимо отключить генерацию debug-пакетов, сбросив определение макроса debug_package в начале spec-файла:
- скрипты сборки приложения в пакете устроены таким образом, что сразу удаляют отладочную информацию из собранных файлов (например, явно вызывают команду strip либо просто не передают опцию «-g» компилятору). В таких случаях необходимо посмотреть, как заставить скрипты сборки оставить отладочную информацию. Иногда этого можно добиться с помощью переменных среды, а иногда может потребоваться патч, изменяющий сборочные скрипты. Если никакие способы не помогают, то можно отключить генерацию debug-пакетов, как описано выше, но делать так не рекомендуется — эти пакеты очень полезны для анализа ошибок в случае падений приложения.
Остановимся подробнее на втором пункте. Большинство приложений позволяют настраивать передаваемые компилятору опции при старте сборки — например, при вызове configure или cmake . Для генерации отладочной информации для подобных приложений вам не нужно прилагать особых усилий — достаточно вместо прямого вызова configure или cmake использовать соответствующие макросы rpm (в нашем примере — %configure2_5x или %cmake соответственно). Если использование макросов не помогает (либо в проекте не используются стандартные средства типа GNU Autotools или CMake), необходимо изучить схему сборки и посмотреть — нельзя ли на нее повлиять как-то еще — например, специфическими опциями либо переменными окружения. Типичными переменными, которые могут повлиять на сборку, являются CFLAGS , CXXFLAGS и CPPFLAGS . Мы рекомендуем выставить эти переменные в макрос %optflags ; при этом может оказаться необходимым перед использованием %%optflags вызвать макрос %%setup_compile_flag (например так сделано в пакете [slock].
Обратите внимание на использование кавычек при выставлении переменных среды — они необходимы, поскольку макрос разворачивается в большой набор опций, разделенных пробелами.
Бывают ситуации, когда повлиять на сборку извне нельзя никак — в скриптах сборки или файлах типа Makefile инструкции сборки «забиты» намертво. В таких случаях необходимо подготовить патч, добавляющий во все вызовы компилятора опцию -g . Помимо опции -g у компилятора, повлиять на отладочную информацию может компоновщик — например, его опции -s и -S , удаляющие подобные данные из результирующих бинарных файлов. Если такие опции явно передаются компоновщику в скриптах сборки либо файлах Makefile, то необходимо подготовить патч, убирающий их — например, так сделано в пакете [kicad].
Error: Can’t locate Some/Perl/Module.pm in @INC
Ошибка означает, что для сборки необходим Perl-модуль Some/Perl/Module.pm , который не был обнаружен в сборочном окружении.
Для исправления ошибки необходимо добавить сборочную зависимость от такого модуля в spec-файл:
Предварительно необходимо убедиться, что такой модуль вообще существует — попробовать его установить с помощью dnf (в rosa2019.1 и новее) либо urpmi (в rosa2016.1):
Если urpmi скажет, что не нашел нужного пакета, то необходимо сначала добавить пакет с модулем в репозитории РОСЫ.
Обратите внимание, что необходимый модуль может находиться в репозитории Contrib, в то время как вы собираете пакет в репозитории Main, Non-free или Restricted. В таком случае Contrib при сборке не используется и требуемый модуль необходимо перенести в репозиторий Main.
Package(s) suggested but not available
Данная ошибка может встречаться при сборке расширений языка R. Она означает, что у собираемого пакета есть необязательная зависимость от каких-то других модулей, которые в сборочной среде отсутствуют. В идеале для каждой такой зависимости необходимо прописать BuildRequires и Requires — например, если ошибка относится к модулю «foo», то нужны зависимости от R-foo:
Предварительно необходимо убедиться, что такой пакет вообще есть в репозиториях — вывод команды «urpmq R-foo» должен быть непуст. Если пакета нет, то желательно его сначала собрать и добавить в репозитории. Однако при сборке может оказаться, что он зависит от того пакета, который вы собирали до этого и для которого вы собственно и хотите добавить зависимость R-foo. В этом случае первый пакет можно собрать и без R-foo, закомментировав при этом команду «%<_bindir>/R CMD check %» в секции %check. После этого можно будет уже собрать R-foo и вернуться к исходному пакету, добавив в него зависимость от R-foo и включив тесты в секции %check
ERROR: dependency(ies) not available
Данная ошибка также может встречаться при сборке расширений языка R, но в отличие от предыдущей, здесь речь идет об обязательных зависимостях сборки. Без них пакет не может быть собран, поэтому вам необходимо добавить в spec-файл соответсвующие BuildRequiers и Requires, а при необходимости предварительно собрать нужные пакеты в репозитории РОСЫ.
hunk FAILED — saving rejects
Данная ошибка означает, что один из патчей (какой именно — указано в выводе rpmbuild) не может быть применен без изменений к новой версии программы. Обычно это означает, что патч необходимо переделать (предварительно определив — нужен ли он еще), что требует определенной квалификации. Однако иногда такая ошибка возникает из-за «строгости» rpmbuild при применении патчей и проблемный патч может быть исправлен в автоматическом режиме с помощью утилиты rediff_patch.
Для этого достаточно склонировать себе Git-репозиторий, перейти в склонированную папку, поместить туда архив с исходным кодом новой версии и запустит rediff_patch, передав ей нужный патч к качестве аргумента:
Если все сложится удачно, то радом со старым патчем «some_patch_to_rediff» появится новый — «some_patch_to_rediff.new» Если же что-то пойдет не так, то в текущей директории останутся папка «rediff_patch» с подпапками вида «myproject.orig» и «myproject» — содержащие соответсвенно оригинальный исходный код и исходный код, получившийся после попытки применить патч. Во второй папке вы найдете файлы с расширениями *rej — это куски патчей, которые применить не удалось.
package ‘foo’ not found
Аналогична следующей ошибке
«No package ‘.*’ found»
Такая ошибка возникает, если пакет проверяет необходимые сборочные зависимости с помощью pkgconfig и не обнаруживает одну из них.
Для исправления ошибки достаточно добавить нужную зависимость сборки в spec-файл:
Предварительно необходимо убедиться, что такая зависимость может быть разрешена — попробовать ее установить с помощью urpmi :
Если urpmi скажет, что не нашел нужного пакета, то необходимо сначала добавить пакет с соответсвующей библиотекой (как правило, она и называется libfoo) в репозитории РОСЫ.
Обратите внимание, что необходимый пакет может находиться в репозитории Contrib, в то время как вы собираете пакет в репозитории Main, Non-free или Restricted. В таком случае Contrib при сборке не используется и требуемый пакет необходимо перенести в репозиторий Main.
/usr/bin/ld: cannot find -lfoo
Данная ошибка возникает при линковке уже собранных объектных файлов и означает, что линкер не смог найти библиотеку «foo». Для исправления ошибки достаточно добавить зависимость от библиотеки в spec-файл. Чтобы определить, как именно эту зависимость прописать, необходимо сначала поискать devel-пакет для библиотеки libfoo (или lib64foo в 64битной системе) с помощью urpmq:
Интересующий нас пакет — тот, что оканчивается на -devel. Посмотрим, что он предоставляет:
Из данного набора необходимо выбрать что-то одно. В РОСЕ отдается предпочтение зависимостям вида pkgconfig(. ), так что в нашем примере в spec-файл необходимо добавить следующую строку:
Если pkgconfig(foo) не окажется в выводе urpmq, то надо добавить зависимость от foo-devel, а если и ее нет — то от libfoo-devel.
Build.PL: No such file or directory
Такая ошибка означает, что предыдущая версия пакета собиралась с помощью скрипт Build.PL, отсутсвующего в новой версии. Часто встречающаяся ситуация — замена Build.PL на Makefile.PL. Если в архиве с исходным кодом новой версии есть скрипт Makefile.PL, то в spec-файле необходимо произвести следующие замены:
- «/Build.PL installdirs=vendor» -> «Makefile.PL INSTALLDIRS=vendor»
- ./Build install destdir=% -> %makeinstall_std
- perl Build.PL install destdir=% -> %makeinstall_std
- ./Build test -> %make test
- ./Build -> %make
Для примера можно посмотреть на пакет .
Если же скрипта Makefile.PL в новой версии также нет, то необходимо смотреть — а что, собственно, есть — файлы CMake, configure или готовый Makefile и модифицировать spec-файл в соответствии с используемой системой сборки.
Makefile.PL: No such file or directory
Возможна и обратная ситуация — вместо Makefile.PL разработчики перешли на Build.PL или что-то еще. Если в архиве с новым исходным кодом есть файл Build.PL, то необходимо провести в spec-файле замены, обратные приведенным в предыдущем пункте:
- «Makefile.PL INSTALLDIRS=vendor» -> «./Build.PL installdirs=vendor»
- %makeinstall_std -> ./Build install destdir=%
- (если предыдущая замена не сработала) %makeinstall_std -> perl Build.PL install destdir=%
- %make test -> ./Build test
- %make -> ./Build
Если же скрипта Build.PL в новой версии также нет, то необходимо смотреть — а что, собственно, есть — файлы CMake, configure или готовый Makefile и модифицировать spec-файл в соответствии с используемой системой сборки.
fg: no job control
Ошибка означает, что внутри spec-файла используется макрос RPM, не поддерживаемый в РОСЕ. Поддерживается или нет каждый конкретный макрос, можно узнать с помощью команды rpm —eval :
Если rpm ничего не знает о таком макросе, то результатом выполнения этой команды будет «%macro_name». В противном случае rpm развернет определение макроса.
Package check «/usr/bin/rpmlint . » failed
Для проверки соблюдения политик сборки и оформления spec-файлов, в Росе используется утилита Rpmlint. Многие ошибки этой утилиты некритичны, однако многие имеют «вес» (badness) и если суммарный вес ошибок для пакета больше или равен 50, то сборка завершается с ошибкой. Если это ваш случай — то первым делом необходимо поискать в логе ошибки, для которых светится «Badness: 50» и исправлять их. Перечень всех ошибок можно найти здесь: Rpmlint Errors
Источник
my requirement is that i want to print some message on screen if rpm install fails in any case at client machine.or display message on screen like rpm install fail due to any of the generated reasons.like other standard rpm gives.
and i am not making any c file or make command in my .spec file . Everything i was doing in spec file itself.plz suggest how to print such type of things in client console using spec file.
yes that is not my concern —test i have give just example.my excet requirement is below spec file content are.
#Pre-Uninstall section
%preun
Processes=`ps -Ao"%p:%a" --cols 150 |
egrep "Launcher|rmiregistry" | grep -v grep | cut -d ":" -f1`
if [ -n "$Processes" ]; then
echo 'xyz is running ,first stop it then uninstall.' > /dev/stderr;
exit 1;
else
echo 'xyz service is not running' >/dev/stdout;
fi
then i try to uninstall the rpm using command
rpm -ev xyz
output :
both message are printed according to service status.i want if client uninstall with option -v then and then it display message on screen otherwise not. how can i do this?
rkb
3,41218 silver badges25 bronze badges
asked Dec 4, 2012 at 8:34
Printing to STDERR
will always be shown to the client. STDOUT
is shown if they install with verbose options.
echo 'Something may be wrong!' > /dev/stderr
answered Dec 4, 2012 at 9:59
Aaron D. MarascoAaron D. Marasco
6,3823 gold badges25 silver badges39 bronze badges
3
You can define %pre
, %post
, %preun
and %postun
sections. They get the number of present installations of the package as a parameter. See here.
The respective section of the RPM book goes into detail concerning these scripts. Essentially, the scripte gets written into a file before execution and then runs.
answered Dec 4, 2012 at 8:48
glglglglglgl
87.8k12 gold badges147 silver badges217 bronze badges
3
Environment
- Red Hat Enterprise Linux (RHEL) 6
- Red Hat Enterprise Linux (RHEL) 7
- Red Hat Enterprise Linux (RHEL) 8
Issue
- Recurring rpm database corruption
- Stale lock files are being left behind in
/var/lib/rpm
-
rpm
commands are failing with messages similar to:# rpm -qa error: rpmdb: BDB0113 Thread/process 5691/140201285396544 failed: BDB1507 Thread died in Berkeley DB library error: db5 error(-30973) from dbenv->failchk: BDB0087 DB_RUNRECOVERY: Fatal error, run database recovery error: cannot open Packages index using db5 - (-30973) error: cannot open Packages database in /var/lib/rpm error: rpmdb: BDB0113 Thread/process 5691/140201285396544 failed: BDB1507 Thread died in Berkeley DB library error: db5 error(-30973) from dbenv->failchk: BDB0087 DB_RUNRECOVERY: Fatal error, run database recovery error: cannot open Packages database in /var/lib/rpm
Resolution
Disclaimer: This utility is meant to be used at the request of support and is not officially supported by Red Hat. Any issues seen with this utility will be handled, if possible, by one of the few engineers associated with it’s creation and not by Bugzilla
Configure the repository
-
RHEL 6:
# curl https://people.redhat.com/kwalker/repos/rpm-deathwatch/rhel6/rpm-deathwatch-rhel-6.repo -o /etc/yum.repos.d/rpm-deathwatch.repo
-
RHEL 7:
# curl https://people.redhat.com/kwalker/repos/rpm-deathwatch/rhel7/rpm-deathwatch-rhel-7.repo -o /etc/yum.repos.d/rpm-deathwatch.repo
-
RHEL 8:
# curl https://people.redhat.com/kwalker/repos/rpm-deathwatch/rhel8/rpm-deathwatch-rhel-8.repo -o /etc/yum.repos.d/rpm-deathwatch.repo
Install required packages
-
You will need
systemtap
installed, as well as thekernel-devel
,kernel-headers
, andkernel-debuginfo
packages for your running kernel.# yum install -y kernel-{devel,headers}-$(uname -r) systemtap && debuginfo-install -y kernel # yum install rpm-deathwatch
-
Note If you are using local repositories, you will need to sync the
rhel-*-server-debug-rpms repository
or the rpms can be manually downloaded from the Package Search
Starting the service
Notes
-
The first time
rpm-deathwatch
is run, thesystemtap
module will take up to a few minutes to build the module. -
If the system is going to reboot before the issue reoccurs, you may want to enable the service
-
The service must be started BEFORE the issue occurs in order to log the signals sent to
rpm
,yum
ordnf
.
RHEL 6
-
To start the service:
# /etc/rc.d/init.d/rpm-deathwatch start Starting rpm-deathwatch
-
Afterwards, check the status of the service:
# /etc/rc.d/init.d/rpm-deathwatch status Service running as 15070
-
To enable it to start during the system startup:
# chkconfig --add rpm-deathwatch # chkconfig rpm-deathwatch on
RHEL 7 and RHEL 8
-
To start the service:
# systemctl start rpm-deathwatch
-
To start the service and enable it to start during the system startup:
# systemctl enable --now rpm-deathwatch
-
Afterwards, check the status of the service:
# systemctl status rpm-deathwatch ● rpm-deathwatch.service - Systemtap module to monitor for termination signals sent to processes accessing the RPM database Loaded: loaded (/usr/lib/systemd/system/rpm-deathwatch.service; enabled; vendor preset: disabled) Active: active (running) since Wed 2020-08-19 08:19:10 EDT; 4s ago Main PID: 17824 (rpm-deathwatch) CGroup: /system.slice/rpm-deathwatch.service ├─17824 /usr/bin/python2 /usr/bin/rpm-deathwatch --name /var/log/rpm-deathwatch └─17834 /usr/bin/stap --suppress-handler-errors -DMAXSTRINGLEN=4096 -p4 -mrpm_deathwatch rpm_deathwatch.stp Aug 19 08:19:10 r7 systemd[1]: Started Systemtap module to monitor for termination signals sent to processes accessing the RPM database. Aug 19 08:19:10 r7 rpm-deathwatch[17824]: INFO:rpm-deathwatch:Checking the environment Aug 19 08:19:11 r7 rpm-deathwatch[17824]: INFO:rpm-deathwatch:Building the systemtap module to report termination signals Aug 19 08:19:35 r7 rpm-deathwatch[17824]: INFO:rpm-deathwatch:Starting monitoring Aug 19 08:19:35 r7 rpm-deathwatch[17824]: INFO:rpm-deathwatch: Opened: /var/log/rpm-deathwatch-08-19-2020-08:19:35 Aug 19 08:19:35 r7 rpm-deathwatch[17824]: INFO:rpm-deathwatch:Writing output to <__main__.files instance at 0x7f70d4a5c560> Aug 19 08:19:35 r7 rpm-deathwatch[17824]: INFO:rpm-deathwatch:Monitoring 18147
Collecting the data
-
Once the issue occurs while the service is running, please attach
rpm-deathwatch-$(date +%m-%d).tar.bz2
, generated by the below command, to a new or existing Red Hat Support Case# tar cjf rpm-deathwatch-$(date +%m-%d).tar.bz2 /var/log/rpm-deathwatch*
Root Cause
-
If
rpm
,yum
ordnf
does not exit cleanly the lock files are left behind. The files (__db001
–__db005
) are left behind in/var/lib/rpm
. We can see thepid
that left the files with:# db_stat -C l -h /var/lib/rpm
-
The problem tends to be that we have no logs or audit configure for what actually killed the process. The most common reason being an automation tool timed out and abruptly ends the process without letting
rpm
clear the lock files. -
The issue can be temporarily resolved by stopping any processes using files under the
/var/lib/rpm
directory and removing these files, or by a reboot which removes these files as well.-
Check processes that are using
/var/lib/rpm
:# fuser -v /var/lib/rpm
-
Stop any services or kill processes reported by
fuser -v /var/lib/rpm
. -
Afterwards, clear the lock files:
# rm /var/lib/rpm/__db*
-
-
If the issue is reoccurring that is when automation becomes the most likely cause.
Diagnostic Steps
Example Logs
-
We can see the «Code 0» means that the commands are completing succesfully. This means the rpm-deathwatch service was started while rpm was working, which is good. We need rpm-deathwatch to run before the issue so it can capture the SIGKILL.
Thu Dec 3 23:56:57 2020 EST: kprocess.exit: rpm(pid:31155) - Code 0 - "rpm -qa" Thu Dec 3 23:56:58 2020 EST: kprocess.exit: yum(pid:31171) - Code 0 - "/usr/bin/python /usr/bin/yum -y update Thu Dec 3 23:56:59 2020 EST: kprocess.exit: yum(pid:31171) - Code 0 - "/usr/bin/python /usr/bin/yum -y update
-
Now we have a SIGKILL. We define the process killed (yum), the pid of yum (31171), output the Process tree of who sent it, and the command that was killed.
Fri Dec 4 00:00:17 2020 EST: sig.send: SIGKILL was sent to yum (pid:31171) by uid:0 using signal_generate Fri Dec 4 00:00:17 2020 EST: sig.send: Process tree: ->systemd[1] - <None found> ->BESClient[3563] - <None found> Fri Dec 4 00:00:17 2020 EST: kprocess.exit: yum(pid:31171) - Code 9 - "/usr/bin/python /usr/bin/yum -y update
-
From this, we can determine that BESClient sent the SIGKILL which killed yum (pid 31171) which was running a «yum update»
-
Product(s)
- Red Hat Enterprise Linux
-
Component
- rpm
- yum
-
Category
- Troubleshoot
-
Tags
- audit
- rhel
- rpm
- yum
This solution is part of Red Hat’s fast-track publication program, providing a huge library of solutions that Red Hat engineers have created while supporting our customers. To give you the knowledge you need the instant it becomes available, these articles may be presented in a raw and unedited form.
Если нам нужно часто устанавливать свои пакеты, у нас может уходить много времени на их конфигурирование и сборку. Мы рассмотрим процесс того, как сделать RPM-пакет для установки на дистрибутив Linux одноименного семейства (например, CentOS или Red Hat). В качестве примера мы соберем NGINX с модулем SPNEGO. Это будет сделано поэтапно — сначала мы соберем простой пакет, потом добавим в него модуль и внесем изменения в конфигурационный файл.
Подготовка системы
1. Устанавливаем необходимые пакеты:
yum install wget rpm-build rpmdevtools
* где:
- wget — утилита для загрузки файлов по сети.
- rpm-build — включает в себя утилиту rpmbuild, с помощью которой будет выполняться сама сборка установочного пакета.
- rpmdevtools — позволит нам использовать утилиту rpmdev-setuptree, с помощью которой мы сможем создать рабочую среду в виде каталогов для сборки.
2. Устанавливаем зависимости:
yum install openssl-devel zlib-devel pcre-devel
* данные пакеты необходимы именно для нашего варианта сборки. Имейте ввиду, что в вашем случае может понадобиться больше зависимостей. Так или иначе, если в системе не будет хватать необходимых пакетов, мы получим ошибку при попытке выполнить сборку RPM.
3. Создаем пользователя.
Делать готовые установочные сборки пакетов очень опасно от пользователя root. Если мы допустим ошибку с путями, файлы могут перетереть или удалить важные для работы директории. Стоит создать отдельного пользователя и работать под ним.
Выполняем команду:
useradd builder -m
* в данном примере мы создадим пользователя builder. Опция -m сразу создаст домашний каталог для пользователя.
Теперь заходим под данным пользователем — последующие команды мы будем выполнять от него:
su — builder
Подготовка среды
Необходимо убедиться, что мы находимся в нужном каталоге для сборки — это может быть произвольная папка, которую мы создадим. В моем примере я буду использовать домашнюю директорию пользователя. Проверить текущее положение можно командой:
$ pwd
Мы должны увидеть что-то на подобие:
/home/builder
Перейти в домашний каталог пользователя можно командой:
$ cd ~
Создадим структуру каталогов для сборки:
$ rpmdev-setuptree
В нашей текущем каталоге должна появиться папка rpmbuild — а в ней:
- BUILD — содержит все файлы, которые появляются при создании пакета.
- RPMS — сюда будут складываться готовые пакеты.
- SOURCES — для исходников, из которых и будут собираться RPM-пакеты.
- SPECS — для файлов с описанием процесса сборки.
- SRPMS — для исходников RPM-файлов.
Мы готовы к загрузке исходника и его подготовке.
На странице загрузки пакетов NGINX мы можем найти пакеты для нужной нам операционной системы. Так как в нашем примере собирается пакет для CentOS (я выбрал 7), то можно перейти сразу в соответствующий каталог.
Находим исходник вида nginx-<версия>.<отметка версии linux>.ngx.src.rpm и копируем на него ссылку:
* в моем примере мне нужен nginx версии 1.19.3.
С помощью скопированной ссылки загружаем исходник:
$ wget https://nginx.org/packages/mainline/centos/7/SRPMS/nginx-1.19.3-1.el7.ngx.src.rpm
Установим скачанный исходник командой:
$ rpm -Uvh nginx-1.19.3-1.el7.ngx.src.rpm
В каталоге rpmbuild/SOURCES появятся исходники для сборки нужной нам версии NGINX.
Собираем установочный RPM-пакет:
$ rpmbuild -bb rpmbuild/SPECS/nginx.spec
В каталоге rpmbuild/RPMS, в зависимости от архитектуры пакета создастся каталог. В моем примере полный путь до созданного пакета — rpmbuild/RPMS/x86_64. В нем мы должны найти 2 файла:
- nginx-1.19.3-1.el7.ngx.x86_64.rpm: пакет для установки.
- nginx-debuginfo-1.19.3-1.el7.ngx.x86_64.rpm: пакет для установки с отладочной информацией.
Пакет создан и готов к установке.
Установка, запуск и удаление
1. Для установки собранного пакета вводим команду:
rpm -Uvh <путь до собранного пакета>
* где rpm вводится с ключами:
- U — обновить, если пакет уже установлен в системе.
- v — вывод информации о ходе процесса.
- h — показывать статус установки.
Список всех ключей можно посмотреть командой rpm —help или man rpm.
Для выполнения данной команды мы должны скопировать на необходимый компьютер наш собранный пакет и зайти в систему под пользователем с правами на установку (как правило, при повышении привилегий до root).
В нашем случае команда будет такой:
rpm -Uvh nginx-1.19.3-1.el7.ngx.x86_64.rpm
* при этом мы должны находиться в каталоге, в котором разместили пакет RPM.
2. Для запуска nginx вводим команды:
systemctl enable nginx
systemctl start nginx
* Первая команда позволит нашему веб-серверу запускаться автоматически. Вторая запустит сервис.
Для проверки состояния сервиса вводим команду:
systemctl status nginx
Я столкнулся с 2-я разными проблема при запуске сервиса.
1) служба не стартовала, выдавая ошибку. В логе говорилось, что нет доступа к файлу /var/run/nginx.pid. Повторный запуск службы решил проблемы.
2) система выдавала ошибку «Unit nginx.service could not be found», которая говорит, что сервиса nginx не существует. Проблема решается вводом команды systemctl daemon-reload, которая перечитываем конфигурационные файлы для systemd.
3. Чтобы удалить пакет сначала запретив автозапуск сервиса и остановим его:
systemctl disable nginx
systemctl stop nginx
Смотрим полное название установленного в системе пакета:
rpm -qa | grep nginx
В моем случае это было:
nginx-1.19.3-1.el7.ngx.x86_64
Для удаления пакета вводим:
rpm -e nginx-1.19.3-1.el7.ngx.x86_64
Добавление модуля
Как говорилось выше, мы добавим модуль SPNEGO в нашу сборку. Для примера, мы будем использовать динамическое подключение данного модуля.
В моем примере необходимо клонировать проект из GIT-репозитория. Для этого необходимо установить одноименную утилиту:
yum install git
Теперь заходим под ранее созданным пользователем builder:
su — builder
Переходим в каталог для сборки. В нашем случае, это домашняя директория:
$ cd ~
Клонируем исходник модуля в директорию /tmp:
$ git clone https://github.com/stnoonan/spnego-http-auth-nginx-module.git /tmp/spnego-http-auth-nginx-module
Ранее мы уже скачивали исходники nginx, поэтому сразу открываем файл nginx.spec:
$ vi rpmbuild/SPECS/nginx.spec
Находим:
%define BASE_CONFIGURE_ARGS …
После последнего —with-… добавим:
—add-dynamic-module=/tmp/spnego-http-auth-nginx-module
Находим
%description
После него добавляем:
%package module-spnego
Group: %{_group}
Requires: nginx = %{?epoch:%{epoch}:}%{main_version}-%{main_release}
Summary: nginx spnego module
%description module-spnego
Dynamic Spnego module for nginx.
После:
%build
… добавляем:
echo ‘load_module «%{_libdir}/nginx/modules/ngx_http_auth_spnego_module.so»;’
> %{buildroot}%{_sysconfdir}/nginx/modules/spnego-http-auth-nginx-module.conf
Находим разделы %files и после них добавим:
%files module-spnego
%{_libdir}/nginx/modules/spnego-http-auth-nginx-module.conf
%{_libdir}/nginx/modules/ngx_http_auth_spnego_module.so
Запускаем сборку:
$ rpmbuild -bb rpmbuild/SPECS/nginx.spec
Для установки нам понадобится 2 RPM-пакета:
- nginx-1.19.3-1.el7.ngx.x86_64.rpm
- nginx-module-spnego-1.19.3-1.el7.ngx.x86_64.rpm
Оба эти пакета будут находиться в каталоге RPMS.
После установки пакета выполняем команду:
nginx -V
Среди полученных опций сборки мы должны увидеть нашу:
… —add-dynamic-module=/tmp/spnego-http-auth-nginx-module …
Также мы должны будем отредактировать конфигурационный файл NGINX, чтобы наши модули подгружались:
vi /etc/nginx/nginx.conf
В корневой секции добавим:
user nginx; worker_processes 1; error_log /var/log/nginx/error.log warn; pid /var/run/nginx.pid; <strong>include /etc/nginx/modules/*.conf;</strong> events { ... |
Ниже по инструкции будет рассказано, как собрать пакет со своим конфигурационным файлом.
Изменение конфигурационного файла NGINX
Перед сборкой мы можем изменить конфигурационный файл веб-сервера, который уже попадет в наш установочный пакет. Так как мы рассматриваем пример работы с модулем spnego, внесем настройки для него.
Открываем файл:
$ vi rpmbuild/SOURCES/nginx.conf
Внесем следующие изменения:
user nginx; worker_processes auto; error_log /var/log/nginx/error.log warn; pid /var/run/nginx.pid; include /etc/nginx/modules/*.conf; events { ... |
* в нашем примере внесено всего 2 изменения:
- worker_processes, который отвечает за распределение нагрузки по ядрам уже давно рекомендуется выставлять в значение auto.
- Также мы дописали строку include /etc/nginx/modules/*.conf, которая укажет нашему веб-серверу подгружать все конфигурационные файлы из каталога modules.
Также активируем для сайта по умолчанию опцию для модуля spnego. Открываем файл:
$ vi rpmbuild/SOURCES/nginx.vh.default.conf
Это файл, который будет находиться по пути /etc/nginx/conf.d/default.conf. Внесем в него изменения:
location / { root /usr/share/nginx/html; index index.html index.htm; auth_gss on; auth_gss_realm test.RU; auth_gss_keytab /etc/http.keytab; auth_gss_service_name HTTP/test.test.ru; } |
Пересобираем RPM:
$ rpmbuild -bb rpmbuild/SPECS/nginx.spec
Выполняем установку новых пакетов на целевом сервере. В нашем примере мы можем переустановить пакеты командами:
rpm -Uvh —force nginx-1.19.3-1.el7.ngx.x86_64.rpm
rpm -Uvh —force nginx-module-spnego-1.19.3-1.el7.ngx.x86_64.rpm
* напоминаю, что у нас используется версия 1.19.3. Чтобы данные команды отработали, необходимо находиться в каталоге, где лежат наши установочные файлы.
Мы должны увидеть изменения в конфигах, которые сделали до сборки.