Dieser Hinweis soll die automatische Git-Halbierung am Beispiel des Linux-Kernels demonstrieren. Mit der anschließenden Suche nach der offiziellen Version, mit der alles kaputt ging und der letzten guten Version.

Toolkit Beschreibung
Das Toolkit [^ 7] ist ein einfaches Projekt zum Zusammenstellen des Kernels und der Module mit einer minimalen Konfiguration, die ausreicht, um in qemu ausgeführt zu werden, einer minimalen Busybox, Konfigurationsdateien und einer kleinen Anzahl von Skripten.
- gcc;)
- binutils
- machen
- qemu
- erwarten (nur wenn Sie die Halbierung aus dem Beispiel ausführen würden)
Der Kernel wird zusammen mit dem initramsfs- Image mit qemu gestartet:
$ qemu-system-x86_64 -cpu host \ -kernel build-linux/arch/x86/boot/bzImage \ -initrd initramfs.cpio.xz \ -nographic -append "nokaslr console=ttyS0 root=/dev/ram" \ -enable-kvm -serial mon:stdio
Es gibt kein Passwort und wir werden sofort in die Konsole geworfen.
Mit diesem Projekt kann eine einfache Halbierung [^ 1] durchgeführt werden.
Achtung! Wenn Sie die unten aufgeführten Manipulationen wiederholen möchten oder als Grundlage für Ihr Projekt verwendet werden, beachten Sie Folgendes:
- Der Kernel ist stark abhängig von den Versionen gcc und binutils , einige Kernel
kann nur mit einer bestimmten Version von gcc zusammenkommen, kann mit zusammenkommen
kleine Änderungen oder Unterdrückung von Fehlern oder gar nicht zu sammeln - Möglicherweise gibt es Probleme mit der neuen Version von binutils (ab Version 2.31).
Laden von Modulen auf Kernelversionen vor v4.16-rc3
Die Versionen von gcc 7.3.0 und binutils 2.30 lassen mich und bauen
Führen Sie die Kernel-Versionen v4.14 bis v5.3-rc2 aus.
Erklärung des Problems
Tatsächlich wird hier ein zusätzliches Problem vorgestellt, das im Rahmen des Hauptproblems gelöst wurde, das als Beispiel dienen sollte.
Irgendwann hat der Pfad in debugfs seinen Wert gegenüber dem ursprünglich in Version 4.14 implementierten geändert :
# ls /sys/kernel/debug/ gpio-mockup-event # ls /sys/kernel/debug/gpio-mockup-event gpio-mockup-A
Ein (gesehen auf v5.3-rc2 ):
# ls /sys/kernel/debug/ gpio-mockup # ls /sys/kernel/debug/gpio-mockup gpiochip1
Was meine Tests für mein Programm gebrochen hat, und die Aufgabe ist herauszufinden, wann, wo und wer, einschließlich der Bestimmung der "guten" und "schlechten" offiziellen Versionen des Kernels.
Lösung mit Git Bisect Run
Wenn Sie dieses Experiment wiederholen, vergessen Sie nicht, Folgendes abzuschließen:
$ git submodule update --init
Führen Sie bisect.sh durch git bisect run aus . Das Skript selbst ist sehr einfach und besteht aus drei Aktionen:
alles klar
alles sammeln
Führen Sie tests / bisect.expect aus (Skript für erwarten)
Der Test startet qemu, wartet auf promt, lädt das gpio-mockup-Modul und prüft, ob Verzeichnisse in / sys / debug / kernel vorhanden sind .
Wir starten den Prozess (es ist dasselbe wie bei der manuellen Halbierung mit Ausnahme des letzten Schritts):
$ git -C linux bisect start $ git -C linux bisect good v4.14 # $ git -C linux bisect bad v5.3-rc2 # Bisecting: 73727 revisions left to test after this (roughly 16 steps) [798bba01b44b0ddf8cd6e542635b37cc9a9b739c] RDMA/core: Fail early if unsupported QP is provided
Führen Sie git bisect run aus :
$ time git -C linux bisect run ../bisect.sh #
Wir warten ... Wir warten ... Wir warten ... Im Allgemeinen habe ich trotz des Versuchs, Montagezeit zu sparen, eine Montage:
$ time ../bisec.sh real 2m1.695s user 11m7.409s sys 2m0.751s
Nach vorläufigen Schätzungen sollte Git Bisect 16 Schritte ausführen .
Und schließlich das Ergebnis:
d51ee07a8de7d6d3f7738a5e74861133fd2d46a0 is the first bad commit commit d51ee07a8de7d6d3f7738a5e74861133fd2d46a0 Author: Bartosz Golaszewski <bgolaszewski@baylibre.com> Date: Thu Jan 17 15:04:23 2019 +0100 gpio: mockup: don't create the debugfs link named after the label User-space tests no longer use it and we're breaking the interface anyway. Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com> :040000 040000 c1a1873f4cfcecace123b72fb036c3861151c9b9 61917a273f4f1f078639463a29acb8a103d50b41 M drivers bisect run success real 42m6.873s user 192m39.291s sys 33m55.932s
Nun, das Ergebnis gab uns die Nummer des Commits an, bei dem alles weg war:
d51ee07a8de7d6d3f7738a5e74861133fd2d46a0 .
Jetzt können Sie sich die Liste aller Schritte ansehen, die git bisect ausgeführt hat :
Git Bisect Log $ git bisect log git bisect start # good: [bebc6082da0a9f5d47a1ea2edc099bf671058bd4] Linux 4.14 git bisect good bebc6082da0a9f5d47a1ea2edc099bf671058bd4 # bad: [609488bc979f99f805f34e9a32c1e3b71179d10b] Linux 5.3-rc2 git bisect bad 609488bc979f99f805f34e9a32c1e3b71179d10b # good: [798bba01b44b0ddf8cd6e542635b37cc9a9b739c] RDMA/core: Fail early if unsupported QP is provided git bisect good 798bba01b44b0ddf8cd6e542635b37cc9a9b739c # good: [e266ca36da7de45b64b05698e98e04b578a88888] Merge tag 'staging-5.1-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging git bisect good e266ca36da7de45b64b05698e98e04b578a88888 # bad: [318222a35bfb0ae9b5ff3e359a583463e6cfcd94] Merge branch 'akpm' (patches from Andrew) git bisect bad 318222a35bfb0ae9b5ff3e359a583463e6cfcd94 # bad: [962d5ecca101e65175a8cdb1b91da8e1b8434d96] Merge tag 'regmap-v5.2' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regmap git bisect bad 962d5ecca101e65175a8cdb1b91da8e1b8434d96 # bad: [f47d633134f7033e3d0c667419d9f8afd69e308d] Merge tag 'tag-chrome-platform-for-v5.1' of git://git.kernel.org/pub/scm/linux/kernel/git/chrome-platform/linux git bisect bad f47d633134f7033e3d0c667419d9f8afd69e308d # good: [6c3f98faddc7f07981c5365ba2f45905ad75fcaa] Merge branch 'i2c/for-5.1' of git://git.kernel.org/pub/scm/linux/kernel/git/wsa/linux git bisect good 6c3f98faddc7f07981c5365ba2f45905ad75fcaa # bad: [2901752c14b8e1b7dd898d2e5245c93e531aa624] Merge tag 'pci-v5.1-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci git bisect bad 2901752c14b8e1b7dd898d2e5245c93e531aa624 # bad: [1a29e857507046e413ca7a4a7c9cd32fed9ea255] Merge tag 'docs-5.1' of git://git.lwn.net/linux git bisect bad 1a29e857507046e413ca7a4a7c9cd32fed9ea255 # bad: [3601fe43e8164f67a8de3de8e988bfcb3a94af46] Merge tag 'gpio-v5.1-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-gpio git bisect bad 3601fe43e8164f67a8de3de8e988bfcb3a94af46 # good: [cf2e8c544cd3b33e9e403b7b72404c221bf888d1] Merge tag 'mfd-next-5.1' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd git bisect good cf2e8c544cd3b33e9e403b7b72404c221bf888d1 # good: [8fab3d713ca36bf4ad4dadec0bf38f5e70b8999d] Merge tag 'gpio-v5.1-updates-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux into devel git bisect good 8fab3d713ca36bf4ad4dadec0bf38f5e70b8999d # bad: [9aac1e336c3ab3824f646224f4b2309b63c51668] Documentation: gpio: legacy: Don't use POLLERR for poll(2) git bisect bad 9aac1e336c3ab3824f646224f4b2309b63c51668 # good: [0248baca03b8f188eccbb991bda2caec4c330975] Merge tag 'intel-gpio-v5.1-1' of git://git.kernel.org/pub/scm/linux/kernel/git/andy/linux-gpio-intel into devel git bisect good 0248baca03b8f188eccbb991bda2caec4c330975 # bad: [e09313ce7ea1706d1642c7d5af103915e69fc6d0] gpio: mockup: change the signature of unlocked get/set helpers git bisect bad e09313ce7ea1706d1642c7d5af103915e69fc6d0 # good: [cbf1e092f2d86e6d7cdb7f9ff8a333f52c826232] gpio: mockup: implement get_multiple() git bisect good cbf1e092f2d86e6d7cdb7f9ff8a333f52c826232 # bad: [83336668b94eb44ecd78a0b7840e43f0859e05cb] gpio: mockup: change the type of 'offset' to unsigned int git bisect bad 83336668b94eb44ecd78a0b7840e43f0859e05cb # bad: [d51ee07a8de7d6d3f7738a5e74861133fd2d46a0] gpio: mockup: don't create the debugfs link named after the label git bisect bad d51ee07a8de7d6d3f7738a5e74861133fd2d46a0 # first bad commit: [d51ee07a8de7d6d3f7738a5e74861133fd2d46a0] gpio: mockup: don't create the debugfs link named after the label
Tatsächlich ist dies der Fehler des ersten Tests (ja - es gibt zwei davon im Test):
send "ls /sys/kernel/debug/\r" expect { "gpio-mockup-event" {} timeout { puts "gpio-mockup-event not found"; exit 1 } }
Eine weitere Prüfung bricht mit dem Commit 2a9e27408e12de455b9fcf66b5d0166f2129579e ab (natürlich wäre es, sie zu trennen, aber faul, also habe ich mir nur die Commits angesehen << next >>):
send "ls /sys/kernel/debug/gpio-mockup-event/\r" expect { "gpio-mockup-A" { puts "gpio-mockup-A found" } timeout { puts "gpio-mockup-A not found"; exit 1 } }
Nun, lassen Sie uns herausfinden, wann das Commit d51ee07a8de7 in den Hauptzweig von Linus gelangt ist und mit welcher offiziellen Kernel-Version es vorhanden ist [^ 6].
Sehen wir uns alle Commits bis d51ee07a8de7 an, die nur Merge-Commits [^ 3] (Merge-Commits) filtern und einen direkten Pfad [^ 4] (Ahnenkette) haben:
$ git log --pretty=oneline d51ee07a8de7d6d3f7738a5e74861133fd2d46a0..master --ancestry-path --merges
Dies gibt uns alle Zusammenführungs-Commits zwischen d51ee07a8de7 und master. Schauen wir uns das Ende der Liste an (nur die letzten drei Einträge werden angezeigt):
3601fe43e8164f67a8de3de8e988bfcb3a94af46 Merge tag 'gpio-v5.1-1' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-gpio 3dda927fdbaac926c50b550ccb51ed18c184468b Merge branch 'ib-qcom-ssbi' into devel 2f7db3c70fdfb22480a1b0aa734664fc256532f2 Merge tag 'gpio-v5.1-updates-for-linus-part-2' of git://git.kernel.org/pub/scm/linux/kernel/git/brgl/linux into devel
Wie wir beim letzten Commit sehen, ist dies eine Übernahme eines Zweigs von git: //git.kernel.org/pub/scm/linux/kernel/git/brgl/linux in git: //git.kernel.org/pub/scm/linux/kernel / git / linusw / linux-gpio devel, und der erste auf der Liste ist die Übernahme des Zweigs des Genossen Linus Walleij (<< Chef >> des GPIO-Subsystems) durch den Genossen Linus Torvalds im Zweig des Meisters.
Es gibt ein sehr gutes Skript [^ 2], das ohne manuelle Arbeit sofort zum Ergebnis führt:
# 3601fe43e816 $ git-find-merge d51ee07a8de7d6d3f7738a5e74861133fd2d46a0 master
Suchen Sie die erste Version nach dem Festschreiben 3601fe43e816 :
$ git name-rev --name-only 3601fe43e816 tags/v5.1-rc1~102
Die Zahl 102 hier ist der Abstand von 3601fe43e816 zu v5.1-rc1 . Überprüfen Sie dies mit der Option des ersten übergeordneten Elements [^ 5]:
$ git -P log --pretty --oneline --first-parent \ --graph 3601fe43e816..v5.1-rc1 | wc -l 102
Alles scheint in Ordnung zu sein. Ich kann sagen, dass die erste offizielle Version des Kernels, in der alles << kaputt war >> v5.1-rc1 , und in Version v5.0 alles in Ordnung war:
$ git describe 3601fe43e816 v5.0-8748-g3601fe43e816
Fazit
Es ist kein Geheimnis, dass es viel mehr Spaß macht, solche Dinge automatisch zu tun. Aufgrund der langen Montagezeit ist es sehr schwierig, eine solche Anzahl von Schritten manuell auszuführen. Sie können einfach vergessen, was Sie getan haben.
Wenn die Anforderungen formuliert sind, können Sie jede Manipulation durchführen, ein spezielles Programm erstellen und es zu initramfs hinzufügen oder etwas Eigenes überprüfen und eine Halbierung zur Hand haben.
Tests können in jeder geeigneten Form durchgeführt werden, während sie die Anforderungen des Git-Halbierungslaufs erfüllen. Darüber hinaus können Sie mit Hilfe von Anwendungsprogrammen (z. B. die gleichen Erwartungen) die Firmware der Karte auf die von Ihnen benötigte Architektur beschränken und diese direkt überprüfen.
[^ 1]: Christian Couder. Vollautomatische Halbierung mit "Git Bisect Run" .
[^ 2]: rmandvikar. Git-Hooks-System (globale, lokale Hooks), Utility-Shell-Skripte, Konfiguration für HOME-Verzeichnis .
[^ 3]: Scott Chacon und Ben Straub. Pro Git Buch .
[^ 4]: void.pointer. Wie funktioniert der Abstammungspfad mit dem Git-Protokoll? .
[^ 5]: Marc G Gauthier. Die erste übergeordnete Option von Git Log .
[^ 6]: Guillaume Morin. Suchen Sie nach einem Zusammenführungs-Commit, das ein bestimmtes Commit enthält .
[^ 7]: Linux-Kernel-Git-Bisect-Vorlage
Originalbild in der Kopfzeile: https://xkcd.com/1597/ .