auto git bisect como um exemplo do kernel do Linux

Esta nota tem como objetivo demonstrar o git bisect automático usando o kernel do Linux como exemplo. Com a busca subseqüente da versão oficial, a partir da qual tudo quebrou e a última versão boa.


Git


Descrição do Kit de Ferramentas


O kit de ferramentas [^ 7] é um projeto simples para montar o kernel e os módulos com uma configuração mínima suficiente para rodar no qemu, no mínimo ocupado, nos arquivos de configuração e em um pequeno número de scripts.


  • gcc;)
  • binutils
  • fazer
  • qemu
  • expect (apenas se você fosse executar o bissetriz a partir do exemplo)

O kernel, junto com a imagem initramsfs , é iniciado usando o 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 

Não há senha e ela imediatamente nos lança no console.


Com este projeto, uma simples bissecção [^ 1] pode ser realizada.


Atenção! Se você planeja repetir as manipulações apresentadas abaixo ou será usado como base para seu projeto, lembre-se:
  1. o kernel depende fortemente das versões gcc e binutils , alguns kernels
    só pode se reunir com uma versão específica do gcc, pode se reunir com
    pequenas edições ou supressão de erros ou não coletar
  2. Pode haver problemas com a nova versão do binutils (a partir da versão 2.31)
    carregando módulos nas versões do kernel anteriores à v4.16-rc3


As versões do gcc 7.3.0 e binutils 2.30 me permitem criar e
execute as versões do kernel v4.14 a v5.3-rc2.

Declaração do problema


Na verdade, um problema adicional é apresentado aqui, resolvido dentro da estrutura do principal, que foi decidido como base, por exemplo.


Em algum momento, o caminho no debugfs mudou seu valor do implementado originalmente na versão v4.14 :


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

Ativado (visto na v5.3-rc2 ):


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

O que interrompeu meus testes para o meu programa e a tarefa é descobrir quando, onde e quem, incluindo a determinação das versões oficiais “boas” e “ruins” do kernel.


Solução com git bisect run


Se você repetir este experimento, não esqueça de concluir:


 $ git submodule update --init 

execute o bisect.sh através do git bisect run , o script em si é muito simples e consiste em três ações:


  1. limpar tudo


  2. colete tudo


  3. execute tests / bisect.expect (script para expectativa)



O teste inicia o qemu, aguarda o prompt , carrega o módulo gpio-mockup e verifica a presença de diretórios em / sys / debug / kernel .
Iniciamos o processo (é o mesmo que para a divisão manual, exceto a última etapa):


  $ 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 

Execute git bisect run :


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

Estamos aguardando ... Estamos aguardando ... Estamos aguardando ... Em geral, apesar de tentar economizar tempo de montagem, tenho uma montagem:


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

De acordo com estimativas preliminares, o git bisect deve lidar com 16 etapas.


E, finalmente, o resultado:


  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 

Bem, o resultado nos deu o número do commit no qual tudo se foi:
d51ee07a8de7d6d3f7738a5e74861133fd2d46a0 .


Agora você pode ver a lista de todas as etapas realizadas pelo git bisect :


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 

De fato, esta é a falha do primeiro teste (sim - existem dois deles no teste):


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

Outra verificação é interrompida com o commit 2a9e27408e12de455b9fcf66b5d0166f2129579e (é claro que seria para separá-los, mas com preguiça, então apenas olhei para os commits << próximo >>):


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

Bem, vamos descobrir quando o commit do d51ee07a8de7 entrou no ramo principal do Linus e com qual versão oficial do kernel ele está presente [^ 6].


Vamos ver todas as confirmações até d51ee07a8de7 filtrando apenas as confirmações de mesclagem [^ 3] (confirmações de mesclagem) e tendo um caminho direto [^ 4] (cadeia ancestral):


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

Isso nos dá todos os commits de mesclagem entre d51ee07a8de7 e master. Vejamos o final da lista (apenas as três últimas entradas são mostradas):


  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 

Como vemos o último commit, esta é uma aquisição de uma ramificação do git: //git.kernel.org/pub/scm/linux/kernel/git/brgl/linux no git: //git.kernel.org/pub/scm/linux/kernel / git / linusw / linux-gpio devel, e o primeiro da lista é a aquisição do ramo do camarada Linus Walleij (<< chefe >> do subsistema GPIO) pelo camarada Linus Torvalds no ramo do mestre.


Existe um script muito bom [^ 2], que imediatamente leva ao resultado sem trabalho manual:


  #       3601fe43e816    $ git-find-merge d51ee07a8de7d6d3f7738a5e74861133fd2d46a0 master 

Encontre a primeira versão após a confirmação 3601fe43e816 :


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

O número 102 aqui é a distância entre 3601fe43e816 e v5.1-rc1 , vamos verificá-lo usando a opção [^ 5] do primeiro pai:


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

Tudo parece estar em ordem. Posso dizer que a primeira versão oficial do kernel na qual tudo << quebrou >> v5.1-rc1 , e na versão v5.0 tudo estava bem:


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

Conclusão


Não é segredo que fazer essas coisas automaticamente é muito mais divertido. É muito difícil executar esse número de etapas manualmente, dado o longo tempo de montagem, você pode simplesmente esquecer o que estava fazendo.


Na verdade, com os requisitos formulados, você pode executar quaisquer manipulações, criar um programa especial e adicionar ao initramfs , ou verificar algo de sua preferência e ter um bisect disponível.


Os testes podem ter qualquer forma conveniente, enquanto cumprem os requisitos da execução do git bisect . Além disso, usando programas aplicativos (por exemplo, a mesma expectativa), você pode limitar o firmware da placa à arquitetura necessária e executar verificações diretamente nela.


[^ 1]: Christian Couder. Bissecção totalmente automatizada com "git bisect run" .


[^ 2]: rmandvikar. Sistema Git hooks (global, local hooks), scripts de shell de utilitário, configuração para o diretório HOME .


[^ 3]: Scott Chacon e Ben Straub. Livro Pro Git .


[^ 4]: void.pointer. Como o caminho da ancestralidade funciona com o git log? .


[^ 5]: Marc G Gauthier. Opção primeiro pai do Git Log .


[^ 6]: Guillaume Morin. Encontre a consolidação de mesclagem, que inclui uma consolidação específica .


[^ 7]: Modelo de git bisect do kernel do Linux


Imagem original usada no cabeçalho: https://xkcd.com/1597/ .

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


All Articles