diff options
Diffstat (limited to 'builder/dnbd3-qcow2-rootfs/readme.md')
-rw-r--r-- | builder/dnbd3-qcow2-rootfs/readme.md | 472 |
1 files changed, 472 insertions, 0 deletions
diff --git a/builder/dnbd3-qcow2-rootfs/readme.md b/builder/dnbd3-qcow2-rootfs/readme.md new file mode 100644 index 00000000..9ad0f968 --- /dev/null +++ b/builder/dnbd3-qcow2-rootfs/readme.md @@ -0,0 +1,472 @@ +# TODO --ommit npd +# TODO Testmenue PW: t + +h1. Evaluation, dissection and modification of Linux remote boot + +h2. Inhalt + +{{toc}} + +#h2. Begriffe + +#* qcow - qemu copy-on-write +#* stage3.1 initramfs +#* stage4 finales System + +h2. Aufgabe + +Es wird ein Skript bzw. Dracut-Modul benötigt, dass ein initramfs basierend auf +systemd baut. Das resultierende initramfs muss Netzwerk-Support bereitstellen, +ein dnbd3 Blockdevice mounten können und einen "switch_root" auf das zuvor +gemountete Dateisystem umsetzen. Das Framework sollte möglichst +Distributionsunabhängig konstruiert sein. Es soll bereits vor dem +"switch_root", also bevor das eigentliche Zielsystem im Root-Verzeichnis +eingebunden werden systemd als init-System zum Einsatz kommen. Die Kernaufgabe +eine initramfs ist es alle nötigen Anwendungen bereitzustellen, die benötigt +werden, um dass finale Zielsystem einzubinden. In dieser konkreten +Aufgabenstellung muss, dass initramfs ein nicht schreibbares Blockgerät +eingebunden werden und eine schreibbare Zwischenshicht (Overlayfilesystem) +zusätzlich eingebunden werden. + +h2. Möglicher Technologien für das Overlaykonzept + +* Dateibasierte Overlay-FS (Union-FS, Alternat-Union-FS, Overlay-FS) + - Funktioniert derzeit nicht auf jedem Zielsystem (Kernel) + - Nicht für den Linux-Kernel zertifiziert oder lässt sich nicht über das + Root-System legen. + - Bei wenigen Änderungen in einer großen Datei muss komplette Datei in + der schreibbaren Schicht gespeichert werden. +* Blockorientierte Overlay-FS (Network-Block-Device, DNBD3, Qemu-Copy-On-Write-Image) + - NBD ist für den Linux-Kernel zertifiziert + - Weniger Netzwerkverkehr nötig, da nur geänderte Blöcke übertragen werden + müssen, statt ganze Dateien zu kopieren. + - DNBD3 hat Failover-Strategien, verzichtet auf komplexe Strategien zum + Schreiben in geänderte Blöcke über das Netzwerk + - Das verfügbare qcow2-Format bietet eine Technologie, um blockorientiert + Änderungen in einer zusätzlichen Dateisystemschicht zu speichern. + +h2. Zielablauf + +Der generelle Ablauf vor bzw. während des Ladens des initramfs und deren +Minilinux-System: + +# Boot PXE +> # Laden des initramfs images +> # Laden des Kernels +# Ausführen des iniramfs +> # Ausführen von Systemd +> > # Bereitstellen aller benötigten Dienste und Hardware (Netzwerk hochbringen) +> > # Mounten des finalen Dateisystems als Wurzel +> > # Wechsel (switch_root) in die finale Distribution +> > # Starten / Weiterausführen von Systemd als Init-System + +h2. Benötigte Pakete zum bauen des initramfs + +> * dracut +# TODO + +h2. Benötigte Pakete innerhalb des resultierenden initramfs + +> * systemd +> * quemu-img +> * quemu-nbd +> * nbd-client +> * dnbd3-client + +h2. Aufsetzen einer Test-Arbeitsumgebung für CentOS + +h3. CentOS7/ArchLinux/RedHat/Ubuntu + VirtualBox + VirtualBoxGuestAdditions + +Aufsetzen des *Dynamic Kernel Module Support*, um einfach neue VBox-Kernel-Module zu aktualisieren: + +> # Aktualisiere Paketdatenbank: @yum update@ +> # Intalliere C-Compiler: @yum install gcc@ +> # Lade erweitertes rpmforfe Repository: @wget http://pkgs.repoforge.org/rpmforge-release/rpmforge-release-0.5.3-1.el7.rf.x86_64.rpm@ +> # Installiere Repository: @rpm -Uvh rpmforge-release-0.5.3-1.el7.rf.x86_64.rpm@ +> # Lade das DKMS-Paket: @wget ftp://rpmfind.net/linux/epel/5/x86_64/dkms-2.2.0.3-29.el5.noarch.rpm@ +> # Installiere DKMS-Paket: @yum localinstall dkms-2.2.0.3-25.el7.noarch.rpm --nogpgcheck@ +> # Aktiviere rpmforge Repository: @yum --enablerepo rpmforge install dkms@ +> # Installiere Entwicklertools zum bauen von Paketen: @yum groupinstall "Development Tools"@ +> # Installiere Metainformation zum Kernel: @yum install kernel-devel@ + +Installieren der VirtualBox-GuestAddtion: + +> # Lege die VirtualBox-GuestAddition-CD ein. +> # Mounte CD: @mount /dev/sr0 /mnt/ && cd /mnt/ && ./VBoxLinuxAdditions.run && reboot@ + +Erstellen eines Testboot Eintrags für Grub2: + +> - Füge in ??/etc/grub.d/40_custom?? den folgenden Inhalt hinzu: + +<pre> +menuentry 'test' --class centos --class gnu-linux --class gnu --class os --unrestricted $menuentry_id_option 'gnulinux-3.10.0-123.el7.x86_64-advanced-6c06919a-389a-4a50-8c6b-b086e65db9b0' { + load_video + set gfxpayload=keep + insmod gzio + insmod part_msdos + insmod xfs + set root='hd0,msdos1' + if [ x$feature_platform_search_hint = xy ]; then + search --no-floppy --fs-uuid --set=root --hint-bios=hd0,msdos1 --hint-efi=hd0,msdos1 --hint-baremetal=ahci0,msdos1 --hint='hd0,msdos1' 4236333a-a808-4f6b-b4a6-d963f4a69a25 + else + search --no-floppy --fs-uuid --set=root 4236333a-a808-4f6b-b4a6-d963f4a69a25 + fi + linux16 /vmlinuz-3.10.0-123.el7.x86_64 root=UUID=6c06919a-389a-4a50-8c6b-b086e65db9b0 ro rd.lvm.lv=centos/swap crashkernel=auto rd.lvm.lv=centos/root vconsole.font=latarcyrheb-sun16 vconsole.keymap=de rhgb quiet + initrd16 /initramfs-test.img +} +</pre> + +> - Füge neuen Menüeintrag in die automatisch generierte Grub2 Konfigurations2-Datei hinzu: @grub2-mkconfig -o /boot/grub2/grub.cfg@ + +h2. Bauen eines Test-Initramfs + +Mache ein Backup vom aktuellen initamfs: +@cp -p /boot/initramfs-$(uname -r).img /boot/initramfs-$(uname -r).img.BACKUP@ + +Der folgende Befehl ersetzt das aktuelle Standart Initramfs mit dem neu +gebauten und berücksichtigt dabei alle bisher editierten Dracut-Module in +??/usr/lib/dracut/modules.d??. Die durchschnittliche Größe des resultierenden +initramfs beträgt komprimiert: zwischen 11 und 16 MB. + +<pre><code class="bash"> +dracut --verbose --force /boot/initramfs-3.10.0-123.el7.x86_64.test.img \ + 3.10.0-123.el7.x86_64 +</code></pre> + +h3. Konfiguration + +TODO + +# Configure "cmdline" from "Chapter 8. DRACUT.CMDLINE(7)" in virtualbox in "/boot/startup.sh" for uefi or in "/boot/grub2/grub.cfg" for grub2 + +h2. Bauen eines minimalen individuellen Test-Initramfs + +<pre><code class="bash"> +dracut --verbose --hostonly --force + /boot/initramfs-3.10.0-123.el7.x86_64.test.img \ + 3.10.0-123.el7.x86_64 +</code></pre> + +Die Option "hostonly" veranlasst Dracut dazu nur alle nötigen Abhängigkeiten +für das aktuelle System in das resultierende Initramfs zu installieren. +Andernfalls fügt dracut viele zusätzliche Treiber hinzu, die die Größe der +resultierenden Datei erheblich vergrößern und damit größer wird als nötig. +Die durchschnittliche Größe des resultierenden initramfs beträgt +komprimiert: zwischen 11 und 16 MB. + +h2. Erstellen eines eigenen Dracut-Moduls + +Alle vorhanden Module befinden sich in ??/usr/lib/dracut/modules.d??. + +> # Erstelle ein neues Modul: @mkdir /usr/lib/dracut/modules.d/91test@ +> # Baue neues initramfs und achte darauf, dass ??\*\*Including module: test\*\*?? mit der Command-Line-Option ??--verbose?? ausgegeben wird. +> # Alle Modul-Installations-Informationen sind in der Datei ??module-setup.sh??: @touch /usr/lib/dracut/modules.d/91test/module-setup.sh@ +> # Konfiguriere Modul: +> > # Als erstes erstellt man eine ??check??-Funktion, die lediglich ??0?? + zurückgibt. Diese Funktion wird aufgerufen, wenn entschieden wird, welche + Dracutmodule geladen werden sollen. Durch zurückgeben der ??0?? wird das + Modul beim nächsten bauen eines Initramfs automatisch hinzugefügt ohne + das man es etwas in der ??/etc/dracut.conf?? oder per Command-Line-Option + "--add" angeben muss. Wenn die @$hostonly@ Variable gesetzt ist, dann + wird das Modul auch im "hostonly" Modus geladen. In diesem Fall sollte + die Funktion nur dann ??0?? zurückgeben, wenn das Modul auch wircklich + für den aktuellen Host benötigt wird. Wenn 255 zurückgegeben wird, wird + das Modul nur dann geladen, wenn es von einem andren Modul als + Abhängigkeit deklariert wurde. + +<pre><code class="bash"> +check() { + return 0 +} +</code></pre> + +Als nächstes wird eine ??install??-Funktion erstellt. Die ??install??-Funktion +wird aufgerufen, wenn alle nicht Kernel spezifischen Ressourcen installiert +werden sollen. Es können Binärdateien, Skripte und andere statischen Dateien +installiert werden. Um einen Datei im aktuellen Modul-Ordner zu addressieren +sollte die Variable "$moddir" als Prefix eingesetzt werden. +Eine solche Funktion kann beispielsweise einen ??Command-Line-Hook?? triggern, +der modulespezifische ??Kernel-Command-Line-Optionen?? verarbeitet während das +initiale Minilinux bootet. Im folgenden Beispiel werden ??Command-Line-Optionen +mit Priorität 20 vom Shell-Skript ??parse-insmodpost.sh?? gelesen und +ausgewertet. Dadurch muss natürlich auch das entsprechende Skript in das +initramfs kopiert werden. Dies wird durch den Aufruf der Funktion +??inst_simple?? erreicht. + +<pre><code class="bash"> +install() { + inst_hook cmdline 20 "$moddir/parse-cmdline.sh" + inst_simple "$moddir/parse-cmdline.sh" /sbin/insmodpost.sh +} +</code></pre> + +Die ??parse-cmdline.sh?? parst die Kernel-Command-Line für die Argumente +??rd.driver.post??, verhindert, dass die Module automatisch geladen werden und +installiert den Hook ??hook.sh?? in der ??initqueue/settled??. Der Inhalt von +??parse-cmdline.sh?? könnte wie folgt aussehen: + +<pre><code class="bash"> +for p in $(getargs rd.driver.post=); do + echo "blacklist $p" >> /etc/modprobe.d/initramfsblacklist.conf +done +</code></pre> + +In einer ??depends??-Funktion können andere Dracut-Module als Abhängigkeit +deklariert werden. Diese müssen einfach per "echo" als String Leerzeichen +getrennt ausgegeben werden. + +<pre><code class="bash"> +depends() { + echo 'debug virtfs' +} +</code></pre> + +Mit dieser Funktion können zusätzliche benötigte Kernel-Command-Line-Argumente +ausgegeben werden, die benötigt werden um die aktuelle Maschine zu booten. +Die Ausgabe sollte mit einem Leerzeichen beginnen und keine neuen Zeilen +ausgeben. + +<pre><code class="bash"> +cmdline() { + echo 'TODO' +} +</code></pre> + +Mit der Funktion ??installkernel?? sollen alle kernelspezifischen Dateien +installiert werden. Siehe hierzu auch den Abschnitt +??Hilfsfunktionen zur Installation?? + +<pre><code class="bash"> +installkernel() { + TODO +} +</code></pre> + +h2. Hilfsfunktionen zur Installation + +??inst_multiple?? installiert mehrere Binärdateien. Sollten ausführbare Dateien +ohne entsprechendem Pfad ausgewählt werden, wird dracut folgende die Pfade +??/usr/sbin??, ??/sbin??, ??/usr/bin??, ??/bin?? durchsuchen, um den Pfad der +zugehörigen ausführbaren Datei zu ermitteln. Bei dem Kommando-Zeilen-Argument +??-o?? als erster Parameter werden Fehler bei nicht auffindbaren Dateien +unterdrückt. + +??inst_multiple [-o] <file> [ <file> …]?? + +??inst?? installiert eine referenzierte Datei an den korrespondierenden Ort im +??initramfs??. Die Datei wird innerhalb des ??initramfs?? am gleichen Ort zu +finden sein wie auf der Referenzmaschine. Optional kann als zweites Argument +ein anderer Ort für das temporäre Dateisystem angegeben werden. + +??inst <src> [<dst>]?? + +??inst_hook?? installiert eine ausführbare Datei im Pfad ??<src>?? im +Dracut-hook-Ordner ??<hookdir>??. Der Einstiegspunkt wird mit Priorität +??<prio>?? zur Laufzeit des initialen Mini-Linux-Systems ausgeführt. + +??inst_hook <hookdir> <prio> <src>?? + +??inst_rules?? installiert einen oder mehrere udev-Regeln. Nicht-existente +udev-Regeln werden beim bauen des initramfs gemeldet, führen aber nicht zum +Abbruch. + +??inst_rules <udevrule> [ <udevrule> …]?? + +??instmods?? installiert einen oder mehrere Kernel-Module in das initramfs. +??<kernelmodule>?? kann auch ein komplettes Subsystem darstellen, wenn es mit +dem Prefiy "=" beginnt (z.B. "=drivers/net/team"). ??instmods?? sollte nur +innerhalb der ??installkernel()??-Funktion verwendet werden. Ist ??$hostonly?? +gesetzt und das aktuelle Modul nicht im Referenzsystem geladen und wird +demnach nicht in ??/sys/…/uevent MODALIAS?? verwendet, wird dieses nicht in +das initramfs integriert. Soll das Modul in jedem Fall geladen werden, kann +folgende Syntax verwendet werden: + +<pre><code class="bash"> +installkernel() { + hostonly='' instmods <kernelmodule> +} +</code></pre> + +??instmods <kernelmodule> [ <kernelmodule> … ]?? + +h3. Konfiguration + +TODO + +h3. Debugging + +TODO + +h2. Build kernel specific dnbd3 kernel module + +> # Installiere Metainformation zum Kernel: @yum install kernel-devel@ +> # Installiere cmake zum Bauen von dnbd3: @yum install cmake@ +> # Installiere zlib-devel zum Bauen von dnbd3: @yum install zlib-devel@ + +Die kernel header Dateien liegen in: + +/usr/lib/modules/3.10.0-229.1.2.el7.x86_64 + +TOOD + +dnbd3-client -h 132.230.4.1 -i stage4/torben/test -r 1 + +> # Installiere qemu-img: @yum install qemu-img@ +> # Installiere nbd: @wget http://dl.fedoraproject.org/pub/epel/6/x86_64/nbd-2.9.20-7.el6.x86_64.rpm && rpm -Uvh nbd-2.9.20-7.el6.x86_64.rpm@ + +NOTE: Disable NetworkManager to avoid reloading network on boot: systemctl disable NetworkManager + +h2. CentOS7 @rpmbuild@ + +First "Set up RPM build env":http://wiki.centos.org/HowTos/SetupRpmBuildEnvironment +Now in that user's home, e.g. @/home/builder@: +<pre> +# install yumdownloader +yum install yum-utils + +# download source in /home/builder/ +yumdownloader --source systemd + +# should have now have a file ~/systemd-208-20.el7_1.2.src.rpm +# "install" it in ~/rpmbuild +rpm -ivh systemd-208-20.el7_1.2.src.rpm + +# install building deps +yum-builddep ~/rpmbuild/SPECS/systemd.spec + +# now check if everything is working, by running the simple %prep% phase +# (unpacks source & applies patches) +rpmbuild -bp ~/rpmbuild/SPECS/systemd.spec + +# if it worked, we can probably compile +# this runs %prep% and %build% +rpmbuild -bp ~/rpmbuild/SPECS/systemd.spec +</pre> + +dmesg + 998 ping 8.8.8.8 + 999 shutdown .h now + 1000 shutdown -h now + 1001 y search yumdownloader + 1002 y install yum-utils + 1003 yumdownloader --help + 1004 yumdownloader --source glib2 qemu + 1005 yumdownloader --source qemu-img + 1006 ls + 1007 mkdir glib2_source + 1008 cd glib2 + 1009 cd glib2_source/ + 1010 rpm2cpio ../glib2-2.40.0-4.el7.src.rpm | cpio -idmv + 1011 ls + 1012 tar xf glib-2.40.0.tar.xz + 1013 ls + 1014 cd glib-2.40.0 + 1015 ls + 1016 ./configure --enable-static + 1017 make + 1018 ls + 1019 make + 1020 y search zlib + 1021 y search zlib-static + 1022 y install zlib-static + 1023 ./configure --enable-static + 1024 y search libffi + 1025 y install libffi + 1026 y install libffi-devel + 1027 ./configure --enable-static + 1028 make + 1029 ls + 1030 cd build/ + 1031 ls + 1032 .. + 1033 l + 1034 ls + 1035 make install + 1036 .. + 1037 l + 1038 .. + 1039 l + 1040 mkdir qemu-kvm + 1041 cd qemu-kvm + 1042 ls + 1043 rpm2cpio ../qemu-kvm-1.5.3-86.el7_1.1.src.rpm | cpio -idmv + 1044 l + 1045 pwd + 1046 ls + 1047 l + 1048 ls + 1049 .. + 1050 l + 1051 git clone git://git.qemu.org/qemu.git qemu + 1052 ls + 1053 rm qemu-kvm -rf + 1054 rm qemu-kvm-1.5.3-86.el7_1.1.src.rpm + 1055 l + 1056 cd qemu/ + 1057 l + 1058 ./configure --static --target-list=x86_64-linux-user + 1059 y install zlib + 1060 y install zlib-devel + 1061 y install zlib2 + 1062 y search zlib + 1063 y install zlib-static + 1064 y install zlib + 1065 ll /lib64/libz.a + 1066 ./configure --static --target-list=x86_64-linux-user + 1067 make clean + 1068 ./configure --static + 1069 y search zlib + 1070 y search zlib-static..x86_64 + 1071 y search zlib-static.x86_64 + 1072 y install zlib-static.x86_64 + 1073 ldconfig + 1074 ./configure --static + 1075 ./configure --help + 1076 ./configure --help | grep zlib + 1077 y search zlib + 1078 y install zlib-devel zlib-static zlib + 1079 y deinstall zlib + 1080 y remove zlib + 1081 y search libz + 1082 ls + 1083 git submodule update --init dtc + 1084 ./configure --static --target-list=x86_64-linux-user + 1085 find / -name zlib + 1086 find / -name libz + 1087 find / -name *libz* + 1088 find / -name *zlib* + 1089 ls + 1090 ./configure --disable-zlib-test --static --target-list=x86_64-linux-user + 1091 y search base-devel + 1092 y search devel + 1093 yum groupinstall "Development Tools" + 1094 yum groups mark install + 1095 yum group mark install + 1096 yum groupinstall "Development Tools" + 1097 yum groups mark install + 1098 yum grouplist + 1099 y search zlibrary + 1100 y search glibc + 1101 y install glibc-static + 1102 ls + 1103 ./configure --static --target-list=x86_64-linux-user + 1104 y search glib + 1105 y search glib-2 + 1106 y search glib2-devel + 1107 y install glib2-devel + 1108 ./configure --static --target-list=x86_64-linux-user + 1109 git submodule update --init pixman + 1110 ./configure --static --target-list=x86_64-linux-user + 1111 ls + 1112 ll + 1113 make -j3 + 1114 l + 1115 ldd qemu-nbd + 1116 history + +h2. Quellen + +* "Main Page Dracut on kerne.org":https://dracut.wiki.kernel.org/index.php/Main_Page +* "Documentation on kernel.org":https://www.kernel.org/pub/linux/utils/boot/dracut/dracut.html +* "Enable addional repository":http://www.tecmint.com/enable-rpmforge-repository +* "Getting Dynamic Kernel Module Support":http://rpmfind.net/linux/rpm2html/search.php?query=dkms |