Nachdem es in den anderen beiden Beiträgen (Kernel, Xen) um das Bauen des Kernels und Xen von Hand ging, möchte ich heute darüber schreiben, wie ich die Sache ein wenig automatisiert bekommen habe (nur ein wenig) und mir RPMs zum verteilen bastele. Zuerst geht es darum ein RPM für den vanilla Kernel zu bauen und dieses immer Xen tauglich zu halten, danach geht es darum ein Paket für Xen zu bauen, um die Installation zu vereinfachen.
Xen tauglicher Vanilla Kernel RPM handgestrickt für CentOS 6 / RHEL 6
1. Bootstrapping – Einrichten einer passenden Umgebung
Um uns ersteinmal eine geeignete Umgebung zu schaffen, sollten (wie im anderen Vanilla-Kernel-Howto beschrieben) ein paar Development-Pakete installiert sein. Dazu als root
yum groupinstall development yum install ncurses-devel rpmdevtools rpm-devel bc pciutils-devel zlib-devel yum install asciidoc hmaccalc perl-ExtUtils-Embed xmlto audit-libs-devel yum install binutils-devel elfutils-devel elfutils-libelf-devel newt-devel python-devel
Danach sollte man als normaler(!) User eine Umgebung fürs RPM-bauen einrichten. In meinem Fall habe ich den User für dieses Tutorial ‚kernelman1‘ genannt:
rpmdev-setuptree
Damit alle Scripte in ~$user/rpmbuild/SOURCES landen, installieren wir ein Kernel-Source Paket direkt von Centos/Redhat oder einem anderen Klon. Zum Zeitpunkt dieses Howtos ist das bei CentOS 6 zu finden unter:
Da ich mein Specfile auf Basis von FC18 aufgebaut habe (zum Zeitpunkt des Artikels noch die neuste Fedora Version), nutze ich hier nun das Fedora SRPM:
http://dl.fedoraproject.org/pub/fedora/linux/releases/18/Fedora/source/SRPMS/k/kernel-3.6.10-4.fc18.src.rpm
weiterhin nicht als root sondern als User installieren wir jetzt das SRPM:
rpm -i http://vault.centos.org/6.4/updates/Source/SPackages/kernel-2.6.32-358.6.2.el6.src.rpmrpm -i http://dl.fedoraproject.org/pub/fedora/linux/releases/ \ 18/Fedora/source/SRPMS/k/kernel-3.6.10-4.fc18.src.rpm
wobei auch nichts dagegen spricht, das SRPM mit wget herunter zu laden und dann zu installieren.
Im SOURCE-Verzeichnis sollte es nun so aussehen :
[kernelman1@redhat6testvm SOURCES]$ ls 0001-efifb-Skip-DMI-checks-if-the-bootloader-knows-what-i.patch 0001-ext4-ext4_inode_info-diet.patch 0002-ext4-give-i_aiodio_unwritten-a-more-appropriate-name.patch ... merge.pl mod-extra.sh mod-extra-sign.sh ... vmbugon-warnon.patch vt-Drop-K_OFF-for-VC_MUTE.patch weird-root-dentry-name-debug.patch x509.genkey
Wichtig ist hierbei, dass neben unserer Zielconfig „config-x86_64-generic“ auch die Scripte merge.pl, mod-extra.sh und mod-extra-sign.sh vorhanden sind. Unter /home/kernelman1/rpmbuild/SPECS sollte nun auch ein kernel.spec File liegen. Dieses können wir einfach löschen oder überrchreiben.
rm /home/kernelman1/rpmbuild/SPECS/kernel.spec wget http://www.techdudes/download/kernel.spec
kann man dann sicher sein, dass man mit den SPEC files nicht durcheinander kommt.
2. Kernel herunterladen
Als nächstes brauchen wir den aktuellen Kernel. Zum Zeitpunkt des Schreibens war das 3.9.6, bitte vorher auf der Seite schauen, welche Version gerade aktuell ist und den Wget-Aufruf entsprechend anpassen.
mkdir -p /home/kernelman1/Downloads cd /home/kernelman1/Downloads wget https://www.kernel.org/pub/linux/kernel/v3.x/linux-3.9.6.tar.xz tar -xJvf linux-3.9.6.tar.xz cd linux-3.9.6
3.1 Kernel Config erstmalig anpassen
Angenommen wir bauen zum ersten mal einen neuen Kernel, dann ist der Versionssprung von 2.6.32 auf 3.9.x oder höher doch sehr groß. Das würde dafür sorgen, dass wir lange Zeit vor make oldconfig verbringen, daher übernehme ich Anfangs die Konfiguration von Kernel.org und passe sie in einigen Punkten für Xen an. Etwas detaillierter habe ich das ganze im Abschnitt „Kernelconfigs anpassen“ im anderen Xen/Kernel-Tutorial Teil 1 beschrieben. Dieser Schritt ist so nur einmal nötig und stellt unsere erste Config dar, auf der wir aufsetzen und Veränderungen/Updates durchführen.
Menuconfig:
- -> Device Drivers -> Network device support:
- Xen network device frontend driver: *
- Xen backend network device: M
- -> Device Drivers -> Block devices:
- Xen virtual block device support: *
- Xen block-device backend driver: M
[kernelman1@redhat6testvm linux-3.9.6]$ make menuconfig scripts/kconfig/mconf Kconfig # # using defaults found in /boot/config-2.6.32-358.el6.x86_64 # /boot/config-2.6.32-358.el6.x86_64:562:warning: symbol value 'm' invalid for PCCARD_NONSTATIC /boot/config-2.6.32-358.el6.x86_64:2696:warning: symbol value 'm' invalid for MFD_WM8400 /boot/config-2.6.32-358.el6.x86_64:2697:warning: symbol value 'm' invalid for MFD_WM831X /boot/config-2.6.32-358.el6.x86_64:2698:warning: symbol value 'm' invalid for MFD_WM8350 /boot/config-2.6.32-358.el6.x86_64:2711:warning: symbol value 'm' invalid for MFD_WM8350_I2C /boot/config-2.6.32-358.el6.x86_64:2713:warning: symbol value 'm' invalid for AB3100_CORE configuration written to .config *** End of the configuration. *** Execute 'make' to start the build or try 'make help'.
Wichtig ist, dass wir sicherstellen, dass die Xen-Frontendmodule fest einkompiliert werden, und die Backends als Module vorhanden sind (hier ein Auszug aus dem anderen Howto):
Auszug: cat .config | grep -i xen | grep NETDEV:
CONFIG_XEN_NETDEV_FRONTEND=m # CONFIG_XEN_NETDEV_BACKEND is not setzu
CONFIG_XEN_NETDEV_FRONTEND=y CONFIG_XEN_NETDEV_BACKEND=mund von:
CONFIG_XEN_BLKDEV_FRONTEND=m # CONFIG_XEN_BLKDEV_BACKEND is not setzu
CONFIG_XEN_BLKDEV_FRONTEND=y CONFIG_XEN_BLKDEV_BACKEND=m
Wenn die neue Config nun gespeichert ist, kopieren wir sie wieder zurück in unsere Paketbauumgebung:
cp .config /home/kernelman4/rpmbuild/SOURCES/config-x86_64-generic cp ../linux-3.9.6.tar.xz /home/kernelman1/rpmbuild/SOURCES
3.2 Kernelconfig wiederholt anpassen
Damit der neue Kernel mit den gleichen Optionen wie der alte gebaut wird, müssen wir die Konfiguration unseres alten Kernels mit in die neue Konfiguration übernehmen. Dazu kopieren wir zuerst die alte KernelConfig aus unserer Paketbauumgebung zum neuen Kernel.
cp /home/kernelman1/rpmbuild/SOURCES/config-x86_64-generic .config cp: „.config“ überschreiben? y
Um dann die Konfigurationen auf den neusten Stand zu heben, können wir make oldconfig verwenden. Oldconfig übernimmt bekannte Parameter der Konfiguration und fragt anschließend ab, was mit den neu hinzugekommenen Parametern geschehen soll (M=Modul, Y=fest einkompiliert, N=nicht einkompilieren).
Hinweis: Bei einem Update von Kernel 2.6.32 auf 3.9.x oder höher kann das sehr sehr lange dauern bis man alle Optionen bestätigt hat. Evtl. lohnt es sich beim ersten mal die initiale Konfiguration des Kernels von kernel.org zu übernehmen. Hier kann man einfach eine .config über make menuconfig erzeugen. Beim späteren Update sollten dann wirklich nur noch Fragen zu den neuen Features gestellt werden.
Ein Beispiel für make oldconfig wäre hier bei einem Update auf Kernel 3.9.5:
[kernelman1@xs1-xenbau linux-3.9.5]# make oldconfig HOSTCC scripts/basic/fixdep HOSTCC scripts/kconfig/conf.o SHIPPED scripts/kconfig/zconf.tab.c SHIPPED scripts/kconfig/zconf.lex.c SHIPPED scripts/kconfig/zconf.hash.c HOSTCC scripts/kconfig/zconf.tab.o HOSTLD scripts/kconfig/conf scripts/kconfig/conf --oldconfig Kconfig * * Restart config... * * * Real Time Clock * Real Time Clock (RTC_CLASS) [Y/n/?] y Set system time from RTC on startup and resume (RTC_HCTOSYS) [Y/n/?] (NEW) ....*snip*... # # configuration written to .config #
Ist make oldconfig fertig, wurde die neue Konfiguration in der Datei .config (unsichtbar) gespeichert. Diese damit auf die aktuelle Kernelversion angepasste Config kopieren wir nun wieder zurück in unsere RPM-Dev-Umgebung:
cp .config /home/kernelman4/rpmbuild/SOURCES/config-x86_64-generic cp ../linux-3.9.6.tar.xz /home/kernelman1/rpmbuild/SOURCES
4. SPEC File anpassen
Danach passen wir das SPEC-File an die aktuelle Kernelversion an. Für Version 3.9.6 sollte also stable_update auf 6 und sublevel auf 9 gesetzt werden.
vi /home/kernelman1/rpmbuild/SPECS/kernel.spec
... %define base_sublevel 9 # Do we have a -stable update to apply? %define stable_update 5 %define rpmversion 3.%{base_sublevel}.%{stable_update} ...
5. Paket bauen lassen
rpmbuild -ba --target=x86_64 --with nopatches --with vanilla --without tools kernel.spec 2> build-err.log | \tee build-out.log
Es handelt sich hierbei auch mein erstes SPEC-File, also falls jemand Fehler findet, dann gerne ab in die Kommentarbox und schreiben! Im Netz steht schon genug Unfug…
Baustelle
Um ein RPM zu bauen, braucht man ja immer ein SPEC-File um den Paketierungstools die entsprechenden Anweisungen zu geben. Idealerweise macht man das nicht als root, sondern legt sich einen User dafür an. Angemeldet als dieser User kann man mit
rpmdev-setuptree
flott die passenden Verzeichnisse anlegen lassen. Dann muss noch ein älteres Kernel-SRPM installiert werden, damit Scripte wie merge.pl und Makefile.config im SOURCES Ordner landen (als User mit rpm -ivh installieren, nicht als root).
Danach unter /home/$deinuser/rpmbuild/SPECS das Specfile platzieren.
Anschließend ziehen wir den neusten Kernel: und packen ihn aus.
[kernelman4@xs1-xenbau Download]$ pwd
/home/kernelman4/Download
[kernelman4@xs1-xenbau Download]$ wget https://www.kernel.org/pub/linux/kernel/v3.x/linux-3.9.5.tar.xz
–2013-06-10 17:00:35– https://www.kernel.org/pub/linux/kernel/v3.x/linux-3.9.5.tar.xz
Auflösen des Hostnamen »www.kernel.org«…. 149.20.4.69, 198.145.20.140
Verbindungsaufbau zu www.kernel.org|149.20.4.69|:443… verbunden.
HTTP Anforderung gesendet, warte auf Antwort… 200 OK
Länge: 72107416 (69M) [application/x-xz]
In »»linux-3.9.5.tar.xz«« speichern.
100%[=======================================================================================>] 72.107.416 8,09M/s in 23s
2013-06-10 17:00:58 (3,05 MB/s) – »»linux-3.9.5.tar.xz«« gespeichert [72107416/72107416]
Nun kopieren wir die bisher genutzte Kernel-Konfiguration (.config – Datei) in Verzeichnis mit dem entpackten Kernel. Da ich schon einige Pakete gebastelt hatte, liegt diese Config bereits im Source Ordner eines älteren Kernel Paketes. In diesem Fall baue ich einen Kernel für x86 mit 64 bit, weshalb ich config-x86_64-generic kopiere, um diese zu modifizieren und danach wieder zurückzuspielen. Make Oldconfig wird dann für jede neue Configzeile gegenüber dem alten Kernel abfragen, ob das ganze als Modul (M), fest (Y) oder gar nicht (N) einkompiliert werden soll.
Die passenden Xen-Pakete für unseren Kernel bauen:
yum install libidn-devel curl-devel graphviz gnutls-devel openssl-devel libuuid-devel seabios-bin ipxe-qemu ocaml ocaml-findlib mingw64-binutils