auto git bisect como un ejemplo del kernel de Linux

Esta nota tiene como objetivo demostrar git bisect automático utilizando el kernel de Linux como ejemplo. Con la búsqueda posterior de la versión oficial a partir de la cual todo se rompió y la última buena versión.


Git


Descripción del kit de herramientas


El kit de herramientas [^ 7] es un proyecto simple para ensamblar el núcleo y los módulos con una configuración mínima suficiente para ejecutarse en qemu, mínimo busybox, archivos de configuración y una pequeña cantidad de scripts.


  • gcc;)
  • binutils
  • hacer
  • qemu
  • esperar (solo si fuera a ejecutar bisect desde el ejemplo)

El núcleo, junto con la imagen initramsfs , se inicia usando 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 

No hay contraseña e inmediatamente nos arroja a la consola.


Con este proyecto, se puede llevar a cabo una bisección simple [^ 1].


Atencion Si planea repetir las manipulaciones presentadas a continuación, o se utilizará como base para su proyecto, tenga en cuenta:
  1. el núcleo depende en gran medida de las versiones de gcc y binutils , algunos núcleos
    solo puede juntarse con una versión específica de gcc, puede juntarse con
    pequeñas ediciones o supresión de errores o no recopilar en absoluto
  2. Puede haber problemas con la nueva versión de binutils (a partir de la versión 2.31)
    cargar módulos en versiones de kernel anteriores a v4.16-rc3


Las versiones de gcc 7.3.0 y binutils 2.30 me permiten compilar y
ejecute las versiones de kernel v4.14 a v5.3-rc2.

Declaración del problema.


En realidad, aquí se presenta un problema adicional, resuelto en el marco del principal, que se decidió tomar como base para un ejemplo.


En algún momento, la ruta en debugfs cambió su valor del implementado originalmente en la versión v4.14 :


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

Encendido (visto en v5.3-rc2 ):


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

Lo que rompió mis pruebas para mi programa, y ​​la tarea es encontrar cuándo, dónde y quién, incluida la determinación de las versiones oficiales "buenas" y "malas" del núcleo.


Solución con git bisect run


Si repite este experimento, no olvide completar:


 $ git submodule update --init 

ejecute bisect.sh a través de git bisect run , el script en sí es muy simple y consta de tres acciones:


  1. limpiar todo


  2. colecciona todo


  3. ejecutar tests / bisect.expect (script para esperar)



La prueba inicia qemu, espera el aviso, carga el módulo gpio-mockup y comprueba la presencia de directorios en / sys / debug / kernel .
Comenzamos el proceso (es lo mismo que para la bisección manual con la excepción del último paso):


  $ 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 

Ejecute git bisect run :


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

Estamos esperando ... Estamos esperando ... Estamos esperando ... En general, incluso a pesar de tratar de ahorrar tiempo de ensamblaje, tengo un ensamblaje:


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

Según estimaciones preliminares, git bisect debería manejar 16 pasos.


Y finalmente, el 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 

Bueno, el resultado nos dio el número del commit en el que todo había desaparecido:
d51ee07a8de7d6d3f7738a5e74861133fd2d46a0 .


Ahora puede ver la lista de todos los pasos realizados por 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 hecho, este es el fracaso de la primera prueba (sí, hay dos de ellos en la prueba):


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

Otra comprobación se rompe con el commit 2a9e27408e12de455b9fcf66b5d0166f2129579e (por supuesto, sería separarlos pero perezosos, así que solo miré los commits << siguiente >>):


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

Bueno, descubramos cuándo d51ee07a8de7 commit ingresó a la rama principal de Linus y con qué versión oficial del núcleo está presente [^ 6].


Veamos todos los commits hasta d51ee07a8de7 filtrando solo commits de fusión [^ 3] (commits de fusión) y teniendo una ruta directa [^ 4] (cadena de ascendencia):


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

Esto nos da todos los commits de fusión entre d51ee07a8de7 y master. Veamos el final de la lista (solo se muestran las últimas tres entradas):


  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 el último commit, esta es una adquisición de una rama de git: //git.kernel.org/pub/scm/linux/kernel/git/brgl/linux en git: //git.kernel.org/pub/scm/linux/kernel / git / linusw / linux-gpio devel, y el primero en la lista es la adquisición de la rama del camarada Linus Walleij (<< jefe >> del subsistema GPIO) por el camarada Linus Torvalds en la rama del maestro.


Hay un script muy bueno [^ 2], que conduce inmediatamente al resultado sin trabajo manual:


  #       3601fe43e816    $ git-find-merge d51ee07a8de7d6d3f7738a5e74861133fd2d46a0 master 

Encuentre la primera versión después de commit 3601fe43e816 :


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

El número 102 aquí es la distancia de 3601fe43e816 a v5.1-rc1 , verifíquelo usando la opción de primer padre [^ 5]:


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

Todo parece estar en orden. Puedo decir que la primera versión oficial del kernel en la que todo << se rompió >> v5.1-rc1 , y en la versión v5.0 todo estuvo bien:


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

Conclusión


No es ningún secreto que hacer esas cosas automáticamente es mucho más divertido. Es muy difícil realizar tantos pasos manualmente, dado el largo tiempo de montaje, simplemente puede olvidar lo que estaba haciendo.


En realidad, cuando se formulan los requisitos, puede realizar cualquier manipulación, hacer un programa especial y agregarlo a initramfs , o verificar algo propio y tener bisectos a mano.


Las pruebas pueden realizarse en cualquier forma conveniente mientras cumplen con los requisitos de git bisect run . Además, con la ayuda de programas de aplicación (por ejemplo, lo mismo se espera), puede limitar el firmware de la placa con la arquitectura que necesita y realizar verificaciones directamente en ella.


[^ 1]: Christian Couder. Bisección totalmente automatizada con "git bisect run" .


[^ 2]: rmandvikar. Sistema de enlaces Git (enlaces globales, locales), scripts de shell de utilidad, configuración para el directorio HOME .


[^ 3]: Scott Chacon y Ben Straub. Libro Pro Git .


[^ 4]: void.pointer. ¿Cómo funciona la ruta de ascendencia con git log? .


[^ 5]: Marc G Gauthier. Opción del primer padre de Git Log .


[^ 6]: Guillaume Morin. Encuentra commit de fusión que incluye un commit específico .


[^ 7]: plantilla bisect git del kernel de Linux


Imagen original utilizada en el encabezado: https://xkcd.com/1597/ .

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


All Articles