summaryrefslogblamecommitdiffstats
path: root/readme.md
blob: 9ad0f9688595ec47a735d056deb952b576e29d1d (plain) (tree)
1
2
3
4
5
6
7
8
9


                      

                                                                



          
             
 


                            



                                                                                



























                                                                                     



                                                                         
                 

          







                                                                                 


                                             


          

                                                            
           

             

                
 
                                                    














                                                                                                                                      
                                         








                                                                                       














                                                                                                                                                                                                                         













                                                                                                                                      



                                                                         






                                                                                                                                             
                                                      
 




                                                    









                                                                               

































































                                                                                                                                             
                                                                           








                                                                        
                                                                         










                                                   














                                                                                 
 




























                                                                              






                 











                                                                        




                                                                                                                                             

                                                                                                 
 


























                                                                                   























































































































                                                                               






                                                                                                 

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:
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
}
  • 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.


dracut --verbose --force /boot/initramfs-3.10.0-123.el7.x86_64.test.img \
    3.10.0-123.el7.x86_64

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


dracut --verbose --hostonly --force 
    /boot/initramfs-3.10.0-123.el7.x86_64.test.img \
    3.10.0-123.el7.x86_64

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.

check() {
    return 0
}

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.


install() {
    inst_hook cmdline 20 "$moddir/parse-cmdline.sh"
    inst_simple "$moddir/parse-cmdline.sh" /sbin/insmodpost.sh
}

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:


for p in $(getargs rd.driver.post=); do
    echo "blacklist $p" >> /etc/modprobe.d/initramfsblacklist.conf
done

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.


depends() {
    echo 'debug virtfs'
}

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.


cmdline() {
    echo 'TODO'
}

Mit der Funktion ??installkernel?? sollen alle kernelspezifischen Dateien installiert werden. Siehe hierzu auch den Abschnitt ??Hilfsfunktionen zur Installation??


installkernel() {
    TODO
}

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] [ …]??

??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 []??

??inst_hook?? installiert eine ausführbare Datei im Pfad ???? im Dracut-hook-Ordner ????. Der Einstiegspunkt wird mit Priorität ???? zur Laufzeit des initialen Mini-Linux-Systems ausgeführt.

??inst_hook ??

??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 [ …]??

??instmods?? installiert einen oder mehrere Kernel-Module in das initramfs. ???? 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:


installkernel() {
    hostonly='' instmods 
}

??instmods [ … ]??

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@:

# 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

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