FastNetMon

Tuesday 15 December 2009

Как автоматически обновлять собранный из исходников (sources) модуль при апдейте ядра?

Очень актуальная проблема, т.к. нашим клиентам часто приходится ставить различные драйвера из исходников, а тот факт, что при апдейте ядра все падает - очень нам не нравится.

Такой механизм называется weak-updates, вот информацию нашел - http://linux.dell.com/projects.shtml#dkms

Вот что это такое:

DKMS stands for Dynamic Kernel Module Support. It is designed to create a framework where kernel dependent module source can reside so that it is very easy to rebuild modules as you upgrade kernels. This will allow Linux vendors to provide driver drops without having to wait for new kernel releases while also taking out the guesswork for customers attempting to recompile modules for new kernels.

For veteran Linux users it also provides some advantages since a separate framework for driver drops will remove kernel releases as a blocking mechanism for distributing code. Instead, driver development should speed up as this separate module source tree will allow quicker testing cycles meaning better tested code can later be pushed back into the kernel at a more rapid pace. Its also nice for developers and maintainers as DKMS only requires a source tarball in conjunction with a small configuration file in order to function correctly.



Еще одна хорошая новость - он есть в репозитории Epel и поставить его можно так:
yum install -y dkms


Беглый анализ показал, что dkms добавил свой сервис в автозапуск:
chkconfig --list | grep dkms
dkms_autoinstaller 0:off 1:off 2:on 3:on 4:on 5:on 6:off


Таким образом, судя по презентациям в интернетах, он должен скомпилить модуль при загрузке (2,3,4,5 ран левелы), если вдруг его не обнаружит в новом ядре.

А вот и мануал для CentOS по использованию.

Теперь ставим необходимый набор модулей для сборки модулей ядра: тык

Создаем папку для исходников модуля:
mkdir /usr/src/module-module-version


В моем случае это будет:
mkdir /usr/src/r8168-8.015.00


Переходим в папку:
cd /usr/src/r8168-8.015.00


Стягиваем сорцы в эту папку (и удаляем за собой архивы и прочий мусор):

wget http://download.hetzner.de/drivers/r8168-8.015.00.tar.bz2
tar -xf r8168-8.015.00.tar.bz2
rm -f r8168-8.015.00.tar.bz2
mv r8168-8.015.00/* ./
rm -r r8168-8.015.00



Создаем конфигурационный файл для нашего модуля (в той же папке):

vi dkms.conf


Туда вписываем следующее:

PACKAGE_NAME="r8168"
PACKAGE_VERSION="8.015.00"
BUILT_MODULE_NAME[0]="r8168"
DEST_MODULE_LOCATION[0]="/kernel/drivers/net/"
AUTOINSTALL="yes"


Вот "DEST_MODULE_LOCATION" требует пояснения - это путь, ко которому будет лежать Ваш модуль в /lib/modules, так что если не знаете его, то сходите в папку и посмотрите, по какому пути лежат модули аналогичные Вашему.

Обращаю внимание, что сейчас я все собираю под ядром: Linux libvirt.ru 2.6.18-164.6.1.el5 #1 SMP Tue Nov 3 16:12:36 EST 2009 x86_64 x86_64 x86_64 GNU/Linux (понадобится для последующих тестов).

Теперь добавляем наш модуль в репозиторий dkms:
dkms add -m r8168 -v 8.015.00


Собираем модуль:
dkms build -m r8168 -v 8.015.00


В процессе может последовать вот такой облом:

Kernel preparation unnecessary for this kernel. Skipping...

Building module:
cleaning build area....
make KERNELRELEASE=2.6.18-164.6.1.el5 -C /lib/modules/2.6.18-164.6.1.el5/build M=/var/lib/dkms/r8168/8.015.00/build....

Error! Build of r8168.ko failed for: 2.6.18-164.6.1.el5 (x86_64)
Consult the make.log in the build directory
/var/lib/dkms/r8168/8.015.00/build/ for more information.


Который происходит из-за того, что dkms ищет r8168.ko в текущей папке ( ага, strace ), а он создается в папке src.

Поэтому придется похачить:
mv src/* ./


И попатчить:

- $(MAKE) -C $(KDIR) SUBDIRS=$(PWD)/src modules
+ $(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules


И снова запускаем:
dkms build -m r8168 -v 8.015.00


И в итоге получаем:

Kernel preparation unnecessary for this kernel. Skipping...

Building module:
cleaning build area....
make KERNELRELEASE=2.6.18-164.6.1.el5 -C /lib/modules/2.6.18-164.6.1.el5/build M=/var/lib/dkms/r8168/8.015.00/build.....
cleaning build area....

DKMS: build Completed.


Теперь ставим его в текущее ядро:

dkms install -m r8168 -v 8.015.00


В итоге видим следующее:


r8168.ko:
Running module version sanity check.
- Original module
- No original module exists within this kernel
- Installation
- Installing to /lib/modules/2.6.18-164.6.1.el5/extra/
Adding any weak-modules

depmod....

DKMS: install Completed.


Ну вот и все, модуль в системе:

find /lib | grep 8168
/lib/modules/2.6.18-164.6.1.el5/extra/r8168.ko


А пересоберется ли он под другую версию ядра? Да давайте проверим =) Проверять будем на OpenVZ ядре, поэтому все же поставим его -devel пакет:


yum install -y ovzkernel-devel.x86_64


Выберем его в grub.conf и ребутнемся, но увы - модуль сам не собрался под ovz ядро.

А все потому, что:

dkms build -m r8168 -v 8.015.00

Error! Your kernel source for kernel 2.6.18-164.2.1.el5.028stab066.7 cannot be found at
/lib/modules/2.6.18-164.2.1.el5.028stab066.7/build or /lib/modules/2.6.18-164.2.1.el5.028stab066.7/source.
You can use the --kernelsourcedir option to tell DKMS where it's located.


Почему он не смог найти путь к сорцам OVZ ядра я не понял - possible bug, но вот такой хак помогает:

dkms build -m r8168 -v 8.015.00 --kernelsourcedir=/usr/src/kernels/2.6.18-164.2.1.el5.028stab066.10-x86_64/
dkms install -m r8168 -v 8.015.00


Ну вот и все, в ручном режиме, но успешно:

find /lib | grep 8168
/lib/modules/2.6.18-164.6.1.el5/extra/r8168.ko
/lib/modules/2.6.18-164.2.1.el5.028stab066.7/extra/r8168.ko


Надеюсь, с ядрами основной ветки такого трабла не будет :)

No comments :

Post a Comment

Note: only a member of this blog may post a comment.