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.

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:
- 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 - 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:
limpar tudo
colete tudo
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/ .