auto git bisect comme exemple du noyau Linux

Cette note vise à démontrer la git bisect automatique en utilisant le noyau Linux comme exemple. Avec la recherche ultérieure de la version officielle à partir de laquelle tout s'est cassé et la dernière bonne version.


Git


Description de la boîte à outils


La boîte à outils [^ 7] est un projet simple pour assembler le noyau et les modules avec une configuration minimale suffisante pour fonctionner dans qemu, une boîte occupée minimale, des fichiers de configuration et un petit nombre de scripts.


  • gcc;)
  • binutils
  • faire
  • qemu
  • attendre (seulement si vous alliez exécuter la bissect de l'exemple)

Le noyau, ainsi que l'image initramsfs , est lancé à l'aide de qemu :


$ 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 

Il n'y a pas de mot de passe et il nous jette immédiatement dans la console.


Avec ce projet, une simple bissecte [^ 1] peut être réalisée.


Attention! Si vous prévoyez de répéter les manipulations présentées ci-dessous, ou si vous allez être utilisé comme base pour votre projet, gardez à l'esprit:
  1. le noyau dépend fortement des versions de gcc et binutils , certains noyaux
    ne peut se réunir qu'avec une version spécifique de gcc, peut se réunir avec
    petites modifications ou suppression d'erreurs ou ne pas collecter du tout
  2. Il peut y avoir des problèmes avec la nouvelle version de binutils (à partir de la version 2.31)
    chargement des modules sur les versions du noyau avant v4.16-rc3


Les versions de gcc 7.3.0 et binutils 2.30 me permettent de construire et
exécutez les versions du noyau v4.14 à v5.3-rc2.

Énoncé du problème


En fait, un problème supplémentaire est présenté ici, résolu dans le cadre du principal, qu'il a été décidé de prendre comme base pour un exemple.


À un moment donné, le chemin dans debugfs a changé sa valeur par rapport à celui implémenté à l'origine dans la version v4.14 :


  # ls /sys/kernel/debug/ gpio-mockup-event # ls /sys/kernel/debug/gpio-mockup-event gpio-mockup-A 

Activé (vu sur v5.3-rc2 ):


  # ls /sys/kernel/debug/ gpio-mockup # ls /sys/kernel/debug/gpio-mockup gpiochip1 

Ce qui a cassé mes tests pour mon programme, et la tâche est de trouver quand, où et qui, notamment en déterminant les «bonnes» et «mauvaises» versions officielles du noyau.


Solution avec git bisect run


Si vous répétez cette expérience, n'oubliez pas de terminer:


 $ git submodule update --init 

exécutez bisect.sh via git bisect run , le script lui-même est très simple et se compose de trois actions:


  1. tout effacer


  2. tout collecter


  3. exécutez tests / bisect.expect (script pour expect)



Le test démarre qemu, attend promt, charge le module gpio-mockup et vérifie la présence de répertoires dans / sys / debug / kernel .
Nous commençons le processus (c'est le même que pour la bissectrice manuelle à l'exception de la dernière étape):


  $ 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 

Exécutez git bisect run :


  $ time git -C linux bisect run ../bisect.sh #     

Nous attendons ... Nous attendons ... Nous attendons ... En général, même en essayant de gagner du temps de montage, j'ai un montage:


  $ time ../bisec.sh real 2m1.695s user 11m7.409s sys 2m0.751s 

Selon des estimations préliminaires, git bisect devrait traiter 16 étapes.


Et enfin, le résultat:


  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 

Eh bien, le résultat nous a donné le numéro du commit dans lequel tout était parti:
d51ee07a8de7d6d3f7738a5e74861133fd2d46a0 .


Vous pouvez maintenant consulter la liste de toutes les étapes effectuées par git bisect :


journal git bissect
  $ 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 

En fait, c'est l'échec du premier test (oui - il y en a deux dans le test):


  send "ls /sys/kernel/debug/\r" expect { "gpio-mockup-event" {} timeout { puts "gpio-mockup-event not found"; exit 1 } } 

Une autre vérification rompt avec le commit 2a9e27408e12de455b9fcf66b5d0166f2129579e (bien sûr, ce serait de les séparer mais paresseux, donc j'ai juste regardé les commits << suivant >>):


  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 } } 

Eh bien, découvrons quand le commit d51ee07a8de7 est entré dans la branche principale de Linus et avec quelle version officielle du noyau il est présent [^ 6].


Voyons toutes les validations jusqu'à d51ee07a8de7 filtrant uniquement les validations de fusion [^ 3] ( validations de fusion) et ayant un chemin direct [^ 4] (chaîne d'ascendance):


  $ git log --pretty=oneline d51ee07a8de7d6d3f7738a5e74861133fd2d46a0..master --ancestry-path --merges 

Cela nous donne tous les commits de fusion entre d51ee07a8de7 et master. Regardons la fin de la liste (seules les trois dernières entrées sont affichées):


  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 

Comme nous voyons le dernier commit, il s'agit d'une reprise d'une branche de git: //git.kernel.org/pub/scm/linux/kernel/git/brgl/linux dans git: //git.kernel.org/pub/scm/linux/kernel / git / linusw / linux-gpio devel, et le premier sur la liste est le rachat de la branche du camarade Linus Walleij (<< chef >> du sous-système GPIO) par le camarade Linus Torvalds dans la branche du maître.


Il existe un très bon script [^ 2], qui conduit immédiatement au résultat sans travail manuel:


  #       3601fe43e816    $ git-find-merge d51ee07a8de7d6d3f7738a5e74861133fd2d46a0 master 

Trouvez la première version après commit 3601fe43e816 :


  $ git name-rev --name-only 3601fe43e816 tags/v5.1-rc1~102 

Le nombre 102 ici est la distance de 3601fe43e816 à v5.1-rc1 , vérifions-le en utilisant l'option du premier parent [^ 5]:


  $ git -P log --pretty --oneline --first-parent \ --graph 3601fe43e816..v5.1-rc1 | wc -l 102 

Tout semble être en ordre. Je peux dire que la première version officielle du noyau dans laquelle tout << cassé >> v5.1-rc1 , et dans la version v5.0 tout allait bien:


  $ git describe 3601fe43e816 v5.0-8748-g3601fe43e816 

Conclusion


Ce n'est pas un secret que faire de telles choses automatiquement est beaucoup plus amusant. Il est très difficile de faire un tel nombre d'étapes manuellement, étant donné le long temps d'assemblage, vous pouvez simplement oublier ce que vous faisiez.


En fait, lorsque les exigences sont formulées, vous pouvez effectuer n'importe quelle manipulation, créer un programme spécial et l'ajouter à initramfs , ou vérifier quelque chose de votre choix et avoir la bissect sous la main.


Les tests peuvent être sous n'importe quelle forme pratique tout en répondant aux exigences de git bisect run . De plus, à l'aide de programmes d'application (par exemple, les mêmes attentes), vous pouvez limiter le firmware de la carte avec l'architecture dont vous avez besoin et effectuer des vérifications directement sur celle-ci.


[^ 1]: Christian Couder. Bissection entièrement automatisée avec "git bisect run" .


[^ 2]: rmandvikar. Git hooks system (global, local hooks), scripts shell utilitaires, configuration pour HOME dir .


[^ 3]: Scott Chacon et Ben Straub. Livre Pro Git .


[^ 4]: void.pointer. Comment fonctionne le chemin d'ascendance avec git log? .


[^ 5]: Marc G Gauthier. Option premier parent de Git Log .


[^ 6]: Guillaume Morin. Rechercher un commit de fusion qui inclut un commit spécifique .


[^ 7]: Modèle git bissect du noyau Linux


Image originale utilisée dans l'en-tête: https://xkcd.com/1597/ .

Source: https://habr.com/ru/post/fr462245/


All Articles