Resguardo inicial

This commit is contained in:
lastdragon
2026-09-06 12:53:21 -06:00
parent 662efe3c2a
commit ad2088d178
94853 changed files with 43200404 additions and 0 deletions
@@ -0,0 +1,302 @@
.. include:: ../disclaimer-sp.rst
:Original: Documentation/process/1.Intro.rst
:Translator: Avadhut Naik <avadhut.naik@amd.com>
.. _sp_development_process_intro:
Introducción
============
Resumen ejecutivo
-----------------
El resto de esta sección cubre el alcance del proceso de desarrollo del
kernel y los tipos de frustraciones que los desarrolladores y sus
empleadores pueden encontrar allí. Hay muchas razones por las que el
código del kernel debe fusionarse con el kernel oficial (“mainline”),
incluyendo la disponibilidad automática para los usuarios, el apoyo de la
comunidad en muchas formas, y la capacidad de influir en la dirección del
desarrollo del kernel. El código contribuido al kernel de Linux debe
estar disponible bajo una licencia compatible con GPL.
:ref:`sp_development_process` introduce el proceso de desarrollo, el ciclo
de lanzamiento del kernel y la mecánica de la "ventana de combinación"
(merge window). Se cubren las distintas fases en el desarrollo del parche,
la revisión y, el ciclo de fusión. Hay algunas discusiones sobre
herramientas y listas de correo. Se anima a los desarrolladores que deseen
comenzar con el desarrollo del kernel a encontrar y corregir errores como
ejercicio inicial.
:ref:`sp_development_early_stage` cubre la planificación de proyectos en
etapas tempranas, con énfasis en involucrar a la comunidad de desarrollo
lo antes posible.
:ref:`sp_development_coding` trata sobre el proceso de codificación. Se
discuten varios escollos encontrados por otros desarrolladores. Se cubren
algunos requisitos para los parches, y hay una introducción a algunas de
las herramientas que pueden ayudar a garantizar que los parches del kernel
sean correctos.
:ref:`sp_development_posting` trata sobre el proceso de enviar parches para
su revisión. Para ser tomados en serio por la comunidad de desarrollo,
los parches deben estar correctamente formateados y descritos, y deben
enviarse al lugar correcto. Seguir los consejos de esta sección debería
ayudar a garantizar la mejor recepción posible para su trabajo.
:ref:`sp_development_followthrough` cubre lo que sucede después de publicar
parches; el trabajo está lejos de terminar en ese momento. Trabajar con
revisores es una parte crucial del proceso de desarrollo; esta sección
ofrece varios consejos sobre cómo evitar problemas en esta importante
etapa. Se advierte a los desarrolladores que no asuman que el trabajo está
terminado cuando un parche se fusiona en mainline.
:ref:`sp_development_advancedtopics` introduce un par de temas “avanzados”:
la administración de parches con git y la revisión de parches publicados
por otros.
:ref:`sp_development_conclusion` concluye el documento con punteros a las
fuentes para obtener más información sobre el desarrollo del kernel.
De qué trata este documento
---------------------------
El kernel de Linux, con más de 8 millones de líneas de código y más de
1000 colaboradores en cada versión, en uno de los proyectos de software
libre más grandes y activos que existen. Desde sus humildes comienzos en
1991, este kernel ha evolucionado hasta convertirse en el mejor componente
del sistema operativo que se ejecuta en reproductores de música digital
de bolsillo, PC de escritorio, las supercomputadoras más grandes que
existen y todo tipo de sistemas intermedios. Es una solución robusta,
eficiente, y escalable para casi cualquier situación.
Con el crecimiento de Linux, ha llegado un aumento en el número de
desarrolladores (y empresas) que desean participar en su desarrollo. Los
vendedores de hardware quieren asegurarse de que Linux sea compatible con
sus productos, lo que hace que esos productos sean atractivos para los
usuarios de Linux. Los vendedores de sistemas embebidos, que utilizan
Linux como componente de un producto integrado, quieren que Linux sea lo
más capaz y adecuado posible para tarea en cuestión. Los distribuidores
y otros vendedores de software que basan sus productos en Linux tienen un
claro interés en las capacidades, el rendimiento, y la fiabilidad del
kernel de Linux. Y los usuarios finales, también, a menudo desearán
cambiar Linux para que se adapte mejor a sus necesidades.
Una de las características más convincentes de Linux es que es accesible
a estos desarrolladores; cualquier persona con las habilidades necesarias
puede mejorar Linux e influir en la dirección de su desarrollo. Los
productos propietarios no pueden ofrecer este tipo de apertura, que es una
característica del proceso de software libre. Pero, en todo caso, el
kernel es aún más libre que la mayoría de los otros proyectos de software
libre. Un ciclo típico de desarrollo de kernel de tres meses puede
involucrar a más de 1000 desarrolladores que trabajan para más de 100
empresas diferentes (o sin pertenecer a ninguna empresa).
Trabajar con la comunidad de desarrollo del kernel no es especialmente
difícil. Pero, a pesar de eso, muchos colaboradores potenciales han
experimentado dificultades al tratar de hacer el trabajo del kernel. La
comunidad del kernel ha desarrollado sus propias formas distintivas de
operar, lo que le permite funcionar de manera fluida (y producir un
producto de alta calidad) en un entorno donde miles de líneas de código
se cambian todos los días. Por lo tanto, no es sorprendente que el
proceso de desarrollo del kernel de Linux difiera mucho de los métodos de
desarrollo propietarios.
El proceso de desarrollo del kernel puede parecer extraño e intimidante
para los nuevos desarrolladores, pero hay buenas razones y una sólida
experiencia detrás de él. Un desarrollador que no entienda las formas de
la comunidad del kernel (o, peor aún, que intente burlarse o eludirlas)
tendrá una experiencia frustrante por delante. La comunidad de
desarrollo, si bien es servicial para aquellos que están tratando de
aprender, tiene poco tiempo para aquellos que no escuchan o que no se
preocupan por el proceso de desarrollo.
Se espera que quienes lean este documento puedan evitar esa experiencia
frustrante. Hay mucho material aquí, pero el esfuerzo que implica leerlo
será recompensado en poco tiempo. La comunidad de desarrollo siempre
necesita desarrolladores que ayudan a mejorar el kernel; el siguiente
texto debería ayudarle – o a quienes trabajan para usted, a unirse a
nuestra comunidad.
Créditos
--------
Este documento fue escrito por Jonathan Corbet, corbet@lwn.net. Ha sido
mejorado por los comentarios de Johannes Berg, James Berry, Alex Chiang,
Roland Dreier, Randy Dunlap, Jake Edge, Jiri Kosina, Matt Mackall, Arthur
Marsh, Amanda McPherson, Andrew Morton, Andrew Price, Tsugikazu Shibata y
Jochen Voß.
Este trabajo fue respaldado por la Fundación Linux; gracias especialmente
a Amanda McPherson, quien reconoció el valor de este esfuerzo e hizo que
todo sucediera.
Importancia de integrar el código en el mainline
------------------------------------------------
Algunas empresas y desarrolladores ocasionalmente se preguntan por qué
deberían molestarse en aprender cómo trabajar con la comunidad del
kernel y obtener su código en el kernel mainline (el “mainline” es el
kernel mantenido por Linus Torvalds y utilizado como base por los
distribuidores de Linux. A corto plazo, contribuir con código puede
parecer un gasto evitable; parece más fácil mantener el código separado
y dar soporte a los usuarios directamente. La verdad del asunto es que
mantener el código separado (“fuera del árbol”) es pan para hoy y hambre
para mañana.
Para ilustrar los costos del código fuera-del-árbol, aquí hay algunos
aspectos relevantes del proceso de desarrollo del kernel. La mayoría de
estos se discutirán con mayor detalle más adelante en este documento.
Considerar:
- El código que se ha fusionado con el kernel mainline está disponible
para todos los usuarios de Linux. Estará presente automáticamente en
todas las distribuciones que lo habiliten. No hay necesidad de discos
de controladores, descargas, o las molestias de admitir múltiples
versiones de múltiples distribuciones; todo simplemente funciona, para
el desarrollador y para el usuario. La incorporación al mainline
resuelve un gran número de problemas de distribución y soporte.
- Mientras los desarrolladores del kernel se esfuerzan por mantener una
interfaz estable para el espacio de usuario, la API interna de kernel
está en constante cambio. La falta de una interfaz interna estable es
una decisión deliberada de diseño; permite realizar mejoras
fundamentales en cualquier momento y da como resultado un código de
mayor calidad. Pero uno resultado de esa política es que cualquier
código fuera-del-árbol requiere un mantenimiento constante si va a
funcionar con los nuevos kernels. Mantener el código fuera-del-árbol
requiere una cantidad significativa de trabajo sólo para que ese código
siga funcionando.
En su lugar, el código en el mainline no requiere este trabajo como
resultado de una regla simple que requiere que cualquier desarrollador
que realice un cambio en la API también corrija cualquier código que
se rompa como resultado de ese cambio. Así que, el código fusionado en
el mainline tiene costos de mantenimiento significativamente más bajos.
- Más allá de eso, el código que está en el kernel a menudo será
mejorado por otros desarrolladores. Resultados sorprendentes pueden
provenir de capacitar a su comunidad de usuarios y clientes para mejorar
su producto.
- El código del kernel se somete a revisión, tanto antes como después
de fusionarse con el mainline. No importa cuán fuertes sean las
habilidades del desarrollador original, este proceso de revisión
invariablemente encuentra formas en las que se puede mejorar el código.
A menudo la revisión encuentra errores graves y problemas de seguridad.
Esto es especialmente cierto para el código que se ha desarrollado en
un entorno cerrado; dicho código se beneficia fuertemente de la
revisión por desarrolladores externos. El código fuera-del-árbol es
de menor calidad.
- La participación en el proceso de desarrollo es su manera de influir en
la dirección del desarrollo del kernel. Los usuarios que se quejan
desde el sofa son escuchados, pero los desarrolladores activos tienen
una voz más fuerte – y la capacidad de implementar cambios que hacen
que el kernel funcione mejor para sus necesidades.
- Cuando el código se mantiene por separado, siempre existe la posibilidad
de que un tercero contribuya a una implementación diferente de una
característica similar. Si eso sucede, conseguir que su código
fusionado será mucho más difícil – hasta el punto de la imposibilidad.
Entonces se enfrentará a las desagradables alternativas de (1) mantener
una característica no estándar fuera del árbol indefinidamente, o
(2) abandonar su código y migrar sus usuarios a la versión en el árbol.
- La contribución del código es la acción fundamental que hace que todo
el proceso funcione. Al contribuir con su código, puede agregar nuevas
funcionalidades al kernel y proporcionar capacidades y ejemplos que son
útiles para otros desarrolladores del kernel. Si ha desarrollado código
para Linux (o está pensando en hacerlo), claramente tiene un interés
en el éxito continuo de esta plataforma; contribuir con código es una
de las mejores maneras de ayudar a garantizar ese éxito.
Todo el razonamiento anterior se aplica a cualquier código de kernel
fuera-del-árbol, incluido el código que se distribuye en forma propietaria
y únicamente en binario. Sin embargo, hay factores adicionales que deben
tenerse en cuenta antes de considerar cualquier tipo de distribución de
código de kernel únicamente en binario. Estos incluyen:
- Las cuestiones legales en torno a la distribución de módulos
propietarios del kernel son, en el mejor de los casos, confusas;
bastantes titulares de derechos de autor del kernel creen que la
mayoría de los módulos binarios son productos derivados del kernel y
que, como resultado, su distribución es una violación de la licencia
Pública General de GNU (sobre la que se dirá más adelante). El autor
de este texto no es abogado, y nada en este documento puede considerarse
asesoramiento legal. Solo los tribunales pueden determinar el verdadero
estatus legal de los módulos de código cerrado. Pero la incertidumbre
que acecha a esos módulos está ahí a pesar de todo.
- Los módulos binarios aumentan enormemente la dificultad de depurar
problemas del kernel, hasta el punto de que la mayoría de los
desarrolladores del kernel ni siquiera lo intentarán. Por lo tanto,
la distribución de módulos únicamente en binario hará que sea más
difícil para sus usuarios obtener soporte de la comunidad.
- El soporte también es más difícil para los distribuidores de módulos
únicamente en binario, que deben proporcionar una versión del módulo
para cada distribución y cada versión del kernel que deseen apoyar.
Podría requerir docenas de compilaciones de un solo módulo para
proporcionar una cobertura razonablemente completa, y sus usuarios
tendrán que actualizar su módulo por separado cada vez que
actualicen su kernel.
- Todo lo que se dijo anteriormente sobre la revisión de código se aplica
doblemente al código cerrado. Dado que este código no está disponible
en absoluto, no puede haber sido revisado por la comunidad y, sin duda,
tendrá serios problemas.
Los fabricantes de sistemas embebidos, en particular, pueden verse
tentados a ignorar gran parte de lo que se ha dicho en esta sección
creyendo que están enviando un producto autónomo que utiliza una
versión de kernel congelada y no requiere más desarrollo después de su
lanzamiento. Este argumento desaprovecha el valor de la revisión
generalizad del código y el valor de permitir que sus usuarios agreguen
capacidades a su producto. Pero estos productos también tienen una vida
comercial limitada, después de la cual se debe lanzar una nueva versión.
En ese punto, los vendedores cuyo código esté en el mainline y bien
mantenido estarán en una posición mucho mejor para preparar el nuevo
producto rápidamente para el mercado.
Licencias
---------
El código se contribuye al kernel de Linux bajo varias licencias, pero
todo el código debe ser compatible con la versión 2 de la Licencia
Pública General de GNU (GPLv2), que cubre la distribución del kernel. En
la práctica, esto significa que todas las contribuciones de código están
cubiertas ya sea por la GPLv2 (con, opcionalmente, un lenguaje que permite
la distribución en versiones posteriores de la GPL) o por la licencia BSD
de tres cláusulas. Cualquier contribución que no esté cubierta por una
licencia compatible no será aceptada en el kernel.
No se requieren (ni se solicitan) cesiones de derechos de autor para el
código aportado al kernel. Todo el código fusionado en el kernel
mainline conserva su propiedad original; como resultado, el kernel ahora
tiene miles de propietarios.
Una implicación de esta estructura de propiedad es que cualquier intento
de cambiar la licencia del kernel está condenado a un fracaso casi seguro.
Hay pocos escenarios prácticos en los que se pueda obtener el acuerdo de
todos los titulares de derechos de autor (o eliminar su código del
kernel). Así que, en particular, no hay perspectivas de una migración a
la versión 3 de la GPL en un futuro previsible.
Es imperativo que todo el código aportado al kernel sea legítimamente
software libre. Por esa razón, no se aceptará código de colaboradores
anónimos (o seudónimos). Todos los colaboradores están obligados a
“firmar” su código, indicando que el código puede ser distribuido con
el kernel bajo la GPL. El código que no ha sido licenciado como software
libre por su propietario, o que corre el riesgo de crear problemas
relacionadas con los derechos de autor para el kernel (como el código que
se deriva de esfuerzos de ingeniería inversa que carecen de las garantías
adecuadas) no puede ser contribuido.
Las preguntas sobre cuestiones relacionadas con los derechos de autor son
comunes en las listas de correo de desarrollo de Linux. Normalmente, estas
preguntas no recibirán escasez de respuestas, pero se debe tener en cuenta
que las personas que responden a esas preguntas no son abogados y no
pueden proporcionar consejo legal. Si tiene preguntas legales relacionadas
con el código fuente de Linux, no hay sustituto para hablar con un abogado
que entienda este campo. Confiar en las respuestas obtenidas en listas
técnicas de correo es un asunto arriesgado.
@@ -0,0 +1,543 @@
.. include:: ../disclaimer-sp.rst
:Original: Documentation/process/2.Process.rst
:Translator: Avadhut Naik <avadhut.naik@amd.com>
.. _sp_development_process:
Cómo funciona el proceso de desarrollo
======================================
El desarrollo del kernel de Linux a principios de la década de 1990 fue
un asunto relajado, con un número relativamente pequeño de usuarios y
desarrolladores involucrados. Con una base de usuarios en los millones y
alrededor de 2,000 desarrolladores involucrados durante un año, el kernel
ha tenido que adaptar varios procesos para mantener el desarrollo sin
problemas. Se requiere una comprensión solida de cómo funciona el proceso
para ser una parte efectiva del mismo.
El panorama general
-------------------
Los desarrolladores del kernel utilizan un proceso de lanzamiento basado
en el tiempo de manera flexible, con uno nuevo lanzamiento principal del
kernel ocurriendo cada dos o tres meses. El historial reciente de
lanzamientos se ve así:
====== ==================
5.0 Marzo 3, 2019
5.1 Mayo 5, 2019
5.2 Julio 7, 2019
5.3 Septiembre 15, 2019
5.4 Noviembre 24, 2019
5.5 Enero 6, 2020
====== ==================
Cada lanzamiento 5.x es un lanzamiento principal del kernel con nuevas
características, cambios internos en la API y más. Un lanzamiento típico
puede contener alrededor de 13,000 conjuntos de cambios incluyendo en
varias centenas de miles de líneas de código. 5.x es la vanguardia del
desarrollo del kernel de Linux; el kernel utiliza un modelo de desarrollo
continuo que está integrando continuamente cambios importantes.
Se sigue una disciplina relativamente sencilla con respecto a la fusión
de parches para cada lanzamiento. Al comienzo de cada ciclo de desarrollo,
se dice que la "merge window" (ventana de fusión) está abierta. En ese
momento, el código que se considera lo suficientemente estable (y que es
aceptado por la comunidad de desarrollo) se fusiona en el kernel mainline.
La mayor parte de los cambios para un nuevo ciclo de desarrollo (y todos
los cambios principales) se fusionarán durante este tiempo, a un ritmo
cercano a los 1,000 cambios (“parches” o “conjuntos de cambios”) por
día.
(Aparte, vale la pena señalar que los cambios integrados durante la
ventana de fusión no surgen de la nada; han sido recolectados, probados
y montados con anticipación. Como funciona ese proceso se describirá en
detalle más adelante).
La ventana de fusión dura aproximadamente dos semanas. Al final de este
tiempo, Linux Torvalds declarará que la ventana está cerrada y publicará
el primero de los kernels “rc”. Para el kernel destinado a ser 5.6, por
ejemplo, el lanzamiento al final de la ventana de fusión se llamará
5.6-rc1. El lanzamiento -rc1 señala que el tiempo para fusionar nuevas
características ha pasado y que el tiempo para estabilizar el siguiente
kernel ha comenzado.
Durante las próximas seis a diez semanas, solo los parches que solucionen
problemas deben enviarse al mainline. En ocasiones, se permitirá un cambio
más significativo, pero tales ocasiones son raras; los desarrolladores que
intentan fusionar nuevas características fuera de la ventana de fusión
suelen recibir una recepción poco amistosa. Como regla general, si se
pierde la ventana de fusión de una característica determinada, lo mejor
que puede hacer es esperar al siguiente ciclo de desarrollo. (Se hace una
excepción ocasional para los drivers de hardware que no se admitía
anteriormente; si no afectan a ningún código en árbol, no pueden causar
regresiones y debería ser seguro agregarlos en cualquier momento).
A medida que las correcciones se abren paso en el mainline, la tasa de
parches se ralentizará con el tiempo. Linus lanza nuevos kernels -rc
aproximadamente una vez a la semana; una serie normal llegará a algún
punto entre -rc6 y -rc9 antes de que se considere que el kernel es
suficientemente estable y realice el lanzamiento final. En ese momento,
todo el proceso vuelve a empezar.
Como ejemplo, así fue el ciclo de desarrollo de 5.4 (todas las fechas son
de 2019):
============== =======================================
Septiembre 15 5.3 lanzamiento estable
Septiembre 30 5.4-rc1, la ventana de fusion se cierra
Octubre 6 5.4-rc2
Octubre 13 5.4-rc3
Octubre 20 5.4-rc4
Octubre 27 5.4-rc5
Noviembre 3 5.4-rc6
Noviembre 10 5.4-rc7
Noviembre 17 5.4-rc8
Noviembre 24 5.4 lanzamiento estable
============== =======================================
¿Cómo deciden los desarrolladores cuándo cerrar el ciclo de desarrollo
y crear el lanzamiento estable? La métrica más significativa utilizada
es la lista de regresiones de lanzamientos anteriores. Ningunos errores
son bienvenidos, pero aquellos que rompen sistemas que funcionaron en el
pasado se consideran especialmente graves. Por esta razón, los parches
que causan regresiones se ven con malos ojos y es bastante probable que
se reviertan durante el periodo de estabilización.
El objetivo de los desarrolladores es corregir todas las regresiones
conocidas antes de que se realice el lanzamiento estable. En el mundo
real, este tipo de perfección es difícil de lograr; hay demasiados
variables en un proyecto de este tamaño. Llega un punto en el que
retrasar el lanzamiento final solo empeora el problema; la pila de cambios
que esperan la siguiente ventana de fusión crecerá, creando aún más
regresiones la próxima vez. Por lo tanto, la mayoría de los kernels 5.x
se lanzan con un punado de regresiones conocidas, aunque, con suerte,
ninguna de ellas es seria.
Una vez que se realiza un lanzamiento estable, su mantenimiento continuo
se transfiere al “equipo estable”, actualmente encabezado por Greg
Kroah-Hartman. El equipo estable lanzará actualizaciones ocasionales al
lanzamiento estable utilizando el esquema de numeración 5.x.y. Para ser
considerado para un lanzamiento de actualización, un parche debe
(1) corregir un error significativo y (2) ya estar fusionado en el
mainline para el siguiente kernel de desarrollo. Por lo general, los
kernels recibirán actualizaciones estables durante un poco más de un
ciclo de desarrollo después de su lanzamiento inicial. Así, por ejemplo,
la historia del kernel 5.2 se veía así (todas las fechas en 2019):
============== ===============================
Julio 7 5.2 lanzamiento estable
Julio 14 5.2.1
Julio 21 5.2.2
Julio 26 5.2.3
Julio 28 5.2.4
Julio 31 5.2.5
... ...
Octubre 11 5.2.21
============== ===============================
5.2.21 fue la última actualización estable del lanzamiento 5.2.
Algunos kernels se designan como kernels “a largo plazo”; recibirán
soporte durante un periodo más largo. Consulte el siguiente enlace para
obtener la lista de versiones activas del kernel a largo plazos y sus
maintainers:
https://www.kernel.org/category/releases.html
La selección de un kernel para soporte a largo plazo es puramente una
cuestión de que un maintainer tenga la necesidad y el tiempo para
mantener ese lanzamiento. No hay planes conocidos para ofrecer soporte a
largo plazo para ningún lanzamiento especifico próximo.
Ciclo de vida de un parche
--------------------------
Los parches no van directamente desde el teclado del desarrollador al
kernel mainline. Hay, en cambio, un proceso algo complicado (aunque algo
informal) diseñado para garantizar que cada parche sea revisado en cuanto
a calidad y que cada parche implemente un cambio que es deseable tener en
el mainline. Este proceso puede ocurrir rápidamente para correcciones
menores, o, en el caso de cambios grandes y controvertidos, continuar
durante años. Gran parte de la frustración de los desarrolladores proviene
de la falta de compresión de este proceso o de sus intentos de eludirlo.
Con la esperanza de reducir esa frustración, este documento describirá
cómo un parche entra en el kernel. Lo que sigue a continuación es una
introducción que describe el proceso de una manera tanto idealizada. Un
tratamiento mucho más detallado vendrá en secciones posteriores.
Las etapas por las que pasa un parche son, generalmente:
- Diseño. Aquí es donde se establecen los requisitos reales para el
parche – y la forma en que se cumplirán esos requisitos. El trabajo
de diseño a menudo se realiza sin involucrar a la comunidad, pero es
mejor hacer este trabajo de manera abierta si es posible; puede ahorrar
mucho tiempo rediseñando las cosas más tarde.
- Revisión inicial. Los parches se publican en la lista de correo
relevante y los desarrolladores en esa lista responden con cualquier
comentario que puedan tener. Este proceso debería revelar cualquier
problema importante con un parche si todo va bien.
- Revisión más amplia. Cuando el parche se acerca a estar listo para su
inclusión en el mainline, debe ser aceptado por un maintainer del
subsistema relevante – aunque esta aceptación no es una garantía de
que el parche llegara hasta el mainline. El parche aparecerá en el
árbol de subsistemas del maintainer y en los árboles -next (descritos
a continuación). Cuando el proceso funciona, este paso conduce a una
revisión exhaustiva del parche y al descubrimiento de cualquier
problema resultante de la integración de este parche con el trabajo
realizado por otros.
- Tenga en cuenta que la mayoría de los maintainers también tienen
trabajos diurnos, por lo que fusionar su parche no puede ser su máxima
prioridad. Si su parche está recibiendo comentarios sobre los cambios
que se necesitan, debería realizar esos cambios o justificar por qué
no deberían realizarse. Si su parche no tiene quejas de revisión, pero
no está siendo fusionado por el maintainer apropiado del subsistema o
del driver, debe ser persistente en la actualización del parche
al kernel actual para que se aplique limpiamente y seguir enviándolo
para su revisión y fusión.
- Fusión en el mainline. Eventualmente, un parche exitoso se fusionará
en el repositorio mainline administrado por Linux Torvalds. Mas
comentarios y/o problemas pueden surgir en este momento; es importante
que el desarrollador responda a estos y solucione cualquier problema
que surja.
- Lanzamiento estable. El número de usuarios potencialmente afectados por
el parche es ahora grande, por lo que, una vez más, pueden surgir
nuevos problemas.
- Mantenimiento a largo plazo. Si bien un desarrollador puede olvidarse
del código después de fusionarlo, ese comportamiento tiende a dejar
una impresión negativa en la comunidad de desarrollo. Fusionar el
código elimina parte de la carga de mantenimiento; otros solucionarán
los problemas causados por los cambios en la API. Sin embargo, el
desarrollador original debe seguir asumiendo la responsabilidad del
código si quiere seguir siendo útil a largo plazo.
Uno de los peores errores cometidos por los desarrolladores del kernel
(o sus empleadores) es tratar de reducir el proceso a un solo paso de
“fusión en el mainline”. Este enfoque conduce invariablemente a la
frustración de todos los involucrados.
Cómo se integran los parches en el kernel
-----------------------------------------
Hay exactamente una persona que puede fusionar parches en el repositorio
mainline del kernel: Linus Torvalds. Pero, por ejemplo, de los más de
9,500 parches que se incluyeron en el kernel 2.6.38, solo 112 (alrededor
del 1.3%) fueron elegidos directamente por Linus mismo. El proyecto del
kernel ha crecido mucho desde hace tiempo a un tamaño en el que ningún
desarrollador individual podría inspeccionar y seleccionar todos los
parches sin ayuda. La forma que los desarrolladores del kernel han
abordado este crecimiento es a través del uso de un sistema jerárquico
alrededor de una cadena de confianza.
La base de código del kernel se descompone lógicamente en un conjunto de
subsistemas: redes, soporte de arquitectura especifica, gestión de
memoria, dispositivos de video, etc. La mayoría de los subsistemas tienen
un maintainer designado, un desarrollador que tiene la responsabilidad
general del código dentro de ese subsistema. Estos maintainers de
subsistemas son los guardianes (en cierto modo) de la parte del kernel que
gestionan; son los que (usualmente) aceptarán un parche para incluirlo en
el kernel mainline.
Cada uno de los maintainers del subsistema administra su propia versión
del árbol de fuentes del kernel, generalmente (pero, ciertamente no
siempre) usando la herramienta de administración de código fuente de git.
Herramientas como git (y herramientas relacionadas como quilt o mercurial)
permiten a los maintainers realizar un seguimiento de una lista de
parches, incluida la información de autoría y otros metadatos. En
cualquier momento, el maintainer puede identificar qué parches de su
repositorio no se encuentran en el mainline.
Cuando se abre la ventana de fusión, los maintainers de nivel superior
le pedirán a Linus que “extraiga” los parches que han seleccionado para
fusionar de sus repositorios. Si Linus está de acuerdo, el flujo de
parches fluirá hacia su repositorio, convirtiéndose en parte del kernel
mainline. La cantidad de atención que Linus presta a los parches
específicos recibidos en una operación de extracción varia. Está claro
que, a veces, examina bastante de cerca. Pero, como regla general, Linus
confía en que los maintainers del subsistema no envíen parches
defectuosos al upstream.
Los maintainers de subsistemas, a su vez, pueden extraer parches de otros
maintainers. Por ejemplo, el árbol de red se construye a partir de
parches que se acumulan primero en arboles dedicados a drivers de
dispositivos de red, redes inalámbricas, etc. Esta cadena de repositorios
puede ser arbitrariamente larga, aunque rara vez supera los dos o tres
enlaces. Dado que cada maintainer de la cadena confía en los que
administran árboles de nivel inferior, este proceso se conoce como la
“cadena de confianza”.
Claramente, en un sistema como este, lograr que los parches se integren
en el kernel depende de encontrar el maintainer adecuado. Enviar parches
directamente a Linus no es normalmente la forma correcta de hacerlo.
Árboles siguientes (next)
-------------------------
La cadena de árboles de subsistemas guía el flujo de parches en el
kernel, pero también plantea una pregunta interesante: ¿Qué pasa si
alguien quiere ver todos los parches que se están preparando para la
próxima ventana de fusión? Los desarrolladores estarán interesados en
saber que otros cambios están pendientes para ver si hay algún conflicto
del que preocuparse; un parche que cambia un prototipo de función del
núcleo del kernel, por ejemplo, entrará en conflicto con cualquier otro
parche que utilice la forma anterior de esa función. Los revisores y
probadores quieren tener acceso a los cambios en su forma integrada antes
de que todos esos cambios se integren en el kernel mainline. Uno podría
extraer cambios de todos los árboles de subsistemas interesantes, pero
eso sería un trabajo tedioso y propenso a errores.
La respuesta viene en forma de árboles -next, donde los árboles de
subsistemas se recopilan para pruebas y revisiones. El más antiguo de
estos árboles, mantenido por Andrew Morton, se llama “-mm” (por gestión
de la memoria, que es como comenzó). El árbol “-mm” integra parches
de una larga lista de árboles de subsistemas; también tiene algunos
parches destinados a ayudar con la depuración.
Más allá de eso, -mm contiene una colección significativa de parches
que han sido seleccionados directamente por Andrew. Estos parches pueden
haber sido publicados en una lista de correo o aplicarse a una parte del
kernel para la que no hay un árbol de subsistemas designado. Como
resultado, -mm funciona como una especie de árbol de subsistemas de
último recurso; si no hay otro camino obvio para un parche en el mainline,
es probable que termine en -mm. Los parches misceláneos que se acumulan
en -mm eventualmente se enviarán a un árbol de subsistema apropiado o se
enviarán directamente a Linus. En un ciclo de desarrollo típico,
aproximadamente el 5-10% de los parches que van al mainline llegan allí
a través de -mm.
El parche -mm actual está disponible en el directorio “mmotm” (-mm
del momento) en:
https://www.ozlabs.org/~akpm/mmotm/
Sin embargo, es probable que el uso del árbol MMOTM sea una experiencia
frustrante; existe una posibilidad definitiva de que ni siquiera se
compile.
El árbol principal para la fusión de parches del siguiente ciclo es
linux-next, mantenido por Stephen Rothwell. El árbol linux-next es, por
diseño, una instantánea de cómo se espera que se vea el mainline después
de que se cierre la siguiente ventana de fusión. Los árboles linux-next
se anuncian en las listas de correo linux-kernel y linux-next cuando se
ensamblan; Se pueden descargar desde:
https://www.kernel.org/pub/linux/kernel/next/
Linux-next se ha convertido en una parte integral del proceso de
desarrollo del kernel; todos los parches fusionados durante una ventana
de fusión determinada deberían haber encontrado su camino en linux-next
en algún momento antes de que se abra la ventana de fusión.
Árboles de staging
------------------
El árbol de fuentes del kernel contiene el directorio drivers/staging/,
donde residen muchos subdirectorios para drivers o sistemas de archivos
que están en proceso de ser agregados al árbol del kernel. Permanecen
en drivers/staging mientras aún necesitan más trabajo; una vez
completados, se pueden mover al kernel propiamente dicho. Esta es una
forma de realizar un seguimiento de los drivers drivers que no están a la
altura de la codificación o los estándares de calidad del kernel de
Linux, pero que las personas pueden querer usarlos y realizar un
seguimiento del desarrollo.
Greg Kroah-Hartman mantiene actualmente el árbol de staging. Los drivers
que aun necesitan trabajo se le envían, y cada driver tiene su propio
subdirectorio en drivers/staging/. Junto con los archivos de origen del
driver, también debe haber un archivo TODO en el directorio. El archivo
TODO enumera el trabajo pendiente que el driver necesita para ser aceptado
en el kernel propiamente dicho, así como una lista de personas a las que
Cc’d para cualquier parche para el driver. Las reglas actuales exigen
que los drivers que contribuyen a staging deben, como mínimo, compilarse
correctamente.
El staging puede ser una forma relativamente fácil de conseguir nuevos
drivers en el mainline donde, con suerte, llamarán la atención de otros
desarrolladores y mejorarán rápidamente. Sin embargo, la entrada en el
staging no es el final de la historia; el código que no está viendo
progreso regular eventualmente será eliminado. Los distribuidores también
tienden a ser relativamente reacios a habilitar los drivers de staging.
Por lo tanto, el staging es, en el mejor de los casos, una parada en el
camino para hacia convertirse en un apropiado driver del mainline.
Herramientas
------------
Como se puede ver en el texto anterior, el proceso de desarrollo del
kernel depende en gran medida de la capacidad de dirigir colecciones de
parches en varias direcciones. Todo ello no funcionaría tan bien como lo
hace sin herramientas apropiadamente potentes. Los tutoriales sobre cómo
usar estas herramientas están mucho más allá del alcance de este
documento, pero hay espacio para algunos consejos.
Con mucho, el sistema de gestión de código fuente dominante utilizado
por la comunidad del kernel es git. Git es uno de los varios sistemas de
control de versiones distribuidos que se están desarrollando en la
comunidad de software libre. Está bien ajustado para el desarrollo de
kernel, ya que funciona bastante bien cuando se trata de grandes
repositorios y grandes cantidades de parches. También tiene la reputación
de ser difícil de aprender y usar, aunque ha mejorado con el tiempo.
Algún tipo de familiaridad con git es casi un requisito para los
desarrolladores del kernel; incluso si no lo usan para su propio
trabajo, necesitarán git para mantenerse al día con lo que otros
desarrolladores (y el mainline) están haciendo.
Git ahora está empaquetado por casi todas las distribuciones de Linux.
Hay una página de inicio en:
https://git-scm.com/
Esa página tiene punteros a documentación y tutoriales.
Entre los desarrolladores de kernel que no usan git, la opción más
popular es casi con certeza Mercurial:
https://www.selenic.com/mercurial/
Mercurial comparte muchas características con git, pero proporciona una
interfaz que muchos encuentran más fácil de usar.
Otra herramienta que vale la pena conocer es Quilt:
https://savannah.nongnu.org/projects/quilt/
Quilt es un sistema de gestión de parches, en lugar de un sistema de
gestión de código fuente. No rastrea el historial a lo largo del tiempo;
en cambio, está orientado al seguimiento de un conjunto especifico de
cambios en relación con una base de código en evolución. Algunos de los
principales maintainers de subsistemas utilizan Quilt para gestionar los
parches destinados a ir upstream. Para la gestión de ciertos tipos de
árboles (por ejemplo, -mm) Quilt es la mejor herramienta para el trabajo.
Listas de correo
----------------
Una gran parte del trabajo de desarrollo del kernel de Linux se realiza a
través de listas de correo. Es difícil ser un miembro plenamente funcional
de la comunidad sin unirse al menos a una lista en algún parte. Pero las
listas de correo de Linux también representan un peligro potencial para
los desarrolladores, que corren el riesgo de quedar enterrados bajo una
carga de correo electrónico, incumplir las convenciones utilizadas en las
listas de Linux, o ambas cosas.
La mayoría de las listas de correo del kernel se alojan en kernel.org; la
lista principal se puede encontrar en:
https://subspace.kernel.org
Sin embargo, hay listas alojadas en otros lugares; consulte el archivo
MAINTAINERS para obtener la lista relevante para cualquier subsistema en
particular.
La lista de correo principal para el desarrollo del kernel es, por
supuesto, linux-kernel. Esta lista es un lugar intimidante; el volumen
puede alcanzar 500 mensajes por día, la cantidad de ruido es alta, la
conversación puede ser muy técnica y los participantes no siempre se
preocupan por mostrar un alto grado de cortesía. Pero no hay otro lugar
donde la comunidad de desarrollo del kernel se reúna como un todo; los
desarrolladores que eviten esta lista se perderán información importante.
Hay algunos consejos que pueden ayudar a sobrevivir en el kernel de Linux:
- Haga que la lista se entregue en una carpeta separada, en lugar de su
buzón principal. Uno debe ser capaz de ignorar el flujo durante
periodos prolongados.
- No trate de seguir cada conversación, nadie lo hace. Es importante
filtrar tanto por el tema de interés (aunque tenga en cuenta que las
conversaciones prolongadas pueden alejarse del asunto original sin
cambiar la línea de asunto del correo electrónico) por las personas
que participan.
- No alimente a los trolls. Si alguien está tratando de provocar una
respuesta de enojo, ignórelos.
- Al responder al correo electrónico del kernel de Linux (o al de otras
listas) conserve el encabezado Cc: para todos los involucrados. En
ausencia de una razón solida (como una solicitud explícita), nunca debe
eliminar destinarios. Asegúrese siempre de que la persona a la que está
respondiendo esté en la lista Cc:. Esta convención también hace que no
sea necesario solicitar explícitamente que se le copie en las respuestas
a sus publicaciones.
- Busque en los archivos de la lista (y en la red en su conjunto) antes
de hacer preguntas. Algunos desarrolladores pueden impacientarse con
las personas que claramente no han hecho sus deberes.
- Utilice respuestas intercaladas (“en línea”), lo que hace que su
respuesta sea más fácil de leer. (Es decir, evite top-posting – la
práctica de poner su respuesta encima del texto citado al que está
respondiendo.) Para obtener más información, consulte
:ref:`Documentation/translations/sp_SP/process/submitting-patches.rst <sp_interleaved_replies>`.
- Pregunte en la lista de correo correcta. linux-kernel puede ser el
punto de encuentro general, pero no es el mejor lugar para encontrar
desarrolladores de todos los subsistemas.
El último punto, encontrar la lista de correo correcta, es una fuente
común de errores para desarrolladores principiantes. Alguien que haga
una pregunta relacionada con las redes en linux-kernel seguramente
recibirá una surgencia educada para preguntar en la lista de netdev en su
lugar, ya que esa es la lista frecuentada por la mayoría de los
desarrolladores de redes. Existen otras listas para los subsistemas SCSI,
video4linux, IDE, sistema de archivos, etc. El mejor lugar para buscar
listas de correo es en el archivo MAINTAINERS incluido con el código
fuente del kernel.
Comenzar con el desarrollo del kernel
-------------------------------------
Las preguntas sobre como comenzar con el proceso de desarrollo del kernel
son comunes, tanto de individuos como de empresas. Igualmente comunes son
los pasos en falso que hacen que el comienzo de la relación sea más
difícil de lo que tiene que ser.
Las empresas a menudo buscan contratar desarrolladores conocidos para
iniciar un grupo de desarrollo. De hecho, esta puede ser una técnica
efectiva. Pero también tiende a ser caro y no hace mucho para crecer el
grupo de desarrolladores de kernel experimentados. Es posible poner al
día a los desarrolladores internos en el desarrollo de kernel de Linux,
dada la inversión de algún tiempo. Tomarse este tiempo puede dotar a un
empleador de un grupo de desarrolladores que comprendan tanto el kernel
como la empresa, y que también puedan ayudar a educar a otros. A medio
plazo, este es a menudo el enfoque más rentable.
Los desarrolladores individuales, a menudo, comprensiblemente, no tienen
un lugar para empezar. Comenzar con un proyecto grande puede ser
intimidante; a menudo uno quiere probar las aguas con algo más pequeño
primero. Este es el punto en el que algunos desarrolladores se lanzan a
la creación de parches para corregir errores ortográficos o problemas
menores de estilo de codificación. Desafortunadamente, dicho parches
crean un nivel de ruido que distrae a la comunidad de desarrollo en su
conjunto, por lo que, cada vez más, se los mira con desprecio. Los nuevos
desarrolladores que deseen presentarse a la comunidad no recibirán la
recepción que desean por estos medios.
Andrew Morton da este consejo (traducido) para los aspirantes a
desarrolladores de kernel.
::
El proyecto #1 para los principiantes en el kernel seguramente debería
ser “asegúrese de que el kernel funcione perfectamente en todo momento
en todas las máquinas que pueda conseguir”. Por lo general, la forma
de hacer esto es trabajar con otros para arreglar las cosas (¡esto
puede requerir persistencia!), pero eso está bien, es parte del
desarrollo del kernel.
(https://lwn.net/Articles/283982/)
En ausencia de problemas obvios que solucionar, se aconseja a los
desarrolladores que consulten las listas actuales de regresiones y errores
abiertos en general. Nunca faltan problemas que necesitan solución; al
abordar estos problemas, los desarrolladores ganarán experiencia con el
proceso mientras, al mismo tiempo, se ganarán el respeto del resto de la
comunidad de desarrollo.
@@ -0,0 +1,241 @@
.. include:: ../disclaimer-sp.rst
:Original: Documentation/process/3.Early-stage.rst
:Translator: Carlos Bilbao <carlos.bilbao.osdev@gmail.com> and Avadhut Naik <avadhut.naik@amd.com>
.. _sp_development_early_stage:
Planificación en etapa inicial
==============================
Cuando uno se sienta a planear un proyecto de desarrollo del kernel Linux,
puede ser tentador lanzarse directamente a escribir código. Sin embargo,
como ocurre con cualquier proyecto significativo, gran parte del trabajo
que conduce al éxito es mejor realizarlo antes de escribir la primera línea
de código. Dedicar tiempo a la planificación y comunicación temprana puede
ahorrar mucho más tiempo en adelante.
Especificar el problema
-----------------------
Como en cualquier proyecto de ingeniería, una mejora exitosa del kernel
comienza con una descripción clara del problema a resolver. En algunos
casos, este paso es sencillo: cuando se necesita un driver para un hardware
específico, por ejemplo. En otros, sin embargo, es tentador confundir el
problema real con la solución propuesta, lo que puede generar dificultades.
Consideremos un ejemplo: hace algunos años, los desarrolladores que
trabajaban con audio en Linux buscaban una forma de ejecutar aplicaciones
sin interrupciones u otros artefactos causados por la latencia excesiva en
el sistema. La solución a la que llegaron fue un módulo del kernel
destinado a integrarse en el marco del Módulo de Seguridad de Linux (LSM,
por sus siglas en inglés); este módulo podía configurarse para dar acceso a
aplicaciones específicas al planificador en tiempo real. Este módulo fue
implementado y enviado a la lista de correo del kernel de Linux, donde
inmediatamente encontró problemas.
Para los desarrolladores de audio, este módulo de seguridad era suficiente
para resolver su problema inmediato. Sin embargo, para la comunidad más
amplia del kernel, se veía como un uso indebido del marco LSM (que no está
diseñado para otorgar privilegios a procesos que de otro modo no los
tendrían) y como un riesgo para la estabilidad del sistema. Sus soluciones
preferidas implicaban el acceso a la programación en tiempo real a través
del mecanismo de rlimit a corto plazo, y trabajo continuo para reducir la
latencia a largo plazo.
La comunidad de audio, sin embargo, no podía ver más allá de la solución
particular que habían implementado; no estaban dispuestos a aceptar
alternativas. El desacuerdo resultante dejó a esos desarrolladores
desilusionados con todo el proceso de desarrollo del kernel; uno de ellos
volvió a una lista de audio y publicó esto (traducido):
"Hay un buen número de desarrolladores muy competentes del kernel de Linux, pero tienden a ser opacados por una multitud de arrogantes necios. Intentar comunicar los requisitos de los usuarios a estas personas es una pérdida de tiempo. Son demasiado 'inteligentes' como para escuchar a simples mortales".
Siendo el texto original:
There are a number of very good Linux kernel developers, but they
tend to get outshouted by a large crowd of arrogant fools. Trying
to communicate user requirements to these people is a waste of
time. They are much too "intelligent" to listen to lesser mortals.
(https://lwn.net/Articles/131776/).
La realidad de la situación era diferente; los desarrolladores del kernel
estaban mucho más preocupados por la estabilidad del sistema, el
mantenimiento a largo plazo y encontrar la solución correcta al problema
que por un módulo específico. La moraleja de la historia es centrarse en el
problema, no en una solución específica, y discutirlo con la comunidad de
desarrollo antes de invertir en la creación de un cuerpo de código.
Por lo tanto, al contemplar un proyecto de desarrollo del kernel, se deben
obtener respuestas a un conjunto corto de preguntas:
- ¿Cuál es exactamente el problema que necesita ser resuelto?
- ¿Quiénes son los usuarios afectados por este problema? ¿Qué casos de uso
debería abordar la solución?
- ¿En qué aspectos el kernel actual no logra abordar ese problema?
Solo entonces tiene sentido comenzar a considerar posibles soluciones.
Discusión temprana
------------------
Al planificar un proyecto de desarrollo del kernel, tiene mucho sentido
realizar discusiones con la comunidad antes de lanzarse a la
implementación. La comunicación temprana puede ahorrar tiempo y problemas
de varias maneras:
- Es posible que el problema ya esté siendo abordado por el kernel de
maneras que no haya comprendido. El kernel de Linux es grande y tiene
una serie de características y capacidades que no son inmediatamente
obvias. No todas las capacidades del kernel están documentadas tan bien
como uno quisiera, y es fácil pasar cosas por alto. El autor de este
texto ha visto la publicación de un driver completo que duplicaba uno
existente del que el nuevo autor no tenía conocimiento. El código que
reinventa ruedas existentes no solo es desperdicio; tampoco será aceptado
en el kernel principal.
- Puede haber elementos de la solución propuesta que no serán aceptables
para su inclusión en el kernel principal. Es mejor descubrir problemas
como este antes de escribir el código.
- Es completamente posible que otros desarrolladores ya hayan pensado en el
problema; pueden tener ideas para una mejor solución y estar dispuestos a
ayudar en la creación de esa solución.
Años de experiencia con la comunidad de desarrollo del kernel han enseñado
una lección clara: el código del kernel que se diseña y desarrolla a
puertas cerradas invariablemente tiene problemas que solo se revelan cuando
el código se libera a la comunidad. A veces, estos problemas son graves,
requiriendo meses o años de esfuerzo antes de que el código pueda cumplir
con los estándares de la comunidad del kernel. Algunos ejemplos incluyen:
- La pila de red Devicescape fue diseñada e implementada para sistemas de
un solo procesador. No pudo fusionarse en la rama principal hasta que se
hizo adecuada para sistemas multiprocesador. Adaptar el bloqueo y otros
aspectos en el código es una tarea difícil; como resultado, la fusión de
este código (ahora llamado mac80211) se retrasó más de un año.
- El sistema de archivos Reiser4 incluía una serie de capacidades que, en
opinión de los desarrolladores principales del kernel, deberían haberse
implementado en la capa de sistemas de archivos virtuales. También
incluía funciones que no podían implementarse fácilmente sin exponer el
sistema a bloqueos causados por los usuarios. La revelación tardía de
estos problemas, y la negativa a abordar algunos de ellos, ha mantenido a
Reiser4 fuera del kernel principal.
- El módulo de seguridad AppArmor hacía uso de estructuras de datos
internas del sistema de archivos virtual de maneras que se consideraban
inseguras y poco fiables. Esta preocupación (entre otras) mantuvo a
AppArmor fuera de la rama principal durante años.
En cada uno de estos casos, se podría haber evitado mucho dolor y trabajo
adicional con algunas discusiones tempranas con los desarrolladores del
kernel.
¿Con quién hablar?
-------------------
Cuando los desarrolladores deciden hacer públicas sus ideas, la siguiente
pregunta será: ¿dónde empezar? La respuesta es encontrar la lista de correo
adecuada y el maintainer correcto. Para las listas de correo, la mejor
opción es buscar en el archivo MAINTAINERS un lugar relevante para
publicar. Si existe una lista de subsistema adecuada, es preferible
publicarla allí en lugar de en linux-kernel; es más probable que llegues a
desarrolladores con experiencia en el subsistema relevante y el ambiente
puede ser más propicio.
Encontrar a los maintainers puede ser un poco más difícil. Nuevamente, el
archivo MAINTAINERS es el lugar para empezar. Sin embargo, ese archivo
tiende a no estar siempre actualizado, y no todos los subsistemas están
representados allí. La persona listada en el archivo MAINTAINERS puede, de
hecho, no ser la persona que está actuando en ese rol actualmente. Por lo
tanto, cuando haya dudas sobre a quién contactar, un truco útil es usar git
(y "git log" en particular) para ver quién está activo actualmente en el
subsistema de interés. Mira quién está escribiendo parches y quién, si
alguien, está adjuntando líneas de Signed-off-by a esos parches. Esas son
las personas que estarán mejor posicionadas para ayudar con un nuevo
proyecto de desarrollo.
La tarea de encontrar al maintainer correcto es lo suficientemente
desafiante como para que los desarrolladores del kernel hayan añadido un
script para facilitar el proceso:
::
.../scripts/get_maintainer.pl
Este script devolverá los maintainers actuales de un archivo o directorio
dado cuando se le pase la opción "-f". Si se le pasa un parche en la línea
de comandos, listará a los maintainers que probablemente deberían recibir
copias del parche. Esta es la manera preferida (a diferencia de la opción
"-f") de obtener la lista de personas a las que hay que enviar las copias
de sus parches. Hay varias opciones que regulan cuán agresivamente
get_maintainer.pl buscará maintainers; por favor, ten cuidado al usar las
opciones más agresivas, ya que podrías terminar incluyendo desarrolladores
que no tienen ningún interés real en el código que estás modificando.
Si todo lo demás falla, hablar con Andrew Morton puede ser una forma
efectiva de encontrar a un maintainer para un código específico.
¿Cuándo publicar?
------------------
Si es posible, publicar sus planes en las primeras etapas solo puede ser
útil. Describa el problema que se está resolviendo y cualquier plan que se
haya hecho sobre cómo se llevará a cabo la implementación. Cualquier
información que puedas proporcionar puede ayudar a la comunidad de
desarrollo a ofrecer comentarios útiles sobre el proyecto.
Una cosa desalentadora que puede suceder en esta etapa no es una reacción
hostil, sino, en cambio, poca o ninguna reacción en absoluto. La triste
realidad es que (1) los desarrolladores del kernel tienden a estar
ocupados, (2) no hay escasez de personas con grandes planes y poco código
(o incluso perspectivas de código) para respaldarlos, y (3) nadie está
obligado a revisar o comentar las ideas publicadas por otros. Además, los
diseños de alto nivel a menudo esconden problemas que solo se revelan
cuando alguien realmente intenta implementar esos diseños; por esa razón,
los desarrolladores del kernel prefieren ver el código.
Si una publicación de solicitud de comentarios genera pocos comentarios, no
asuma que significa que no hay interés en el proyecto. Desafortunadamente,
tampoco puedes asumir que no hay problemas con tu idea. Lo mejor que puede
hacer en esta situación es seguir adelante, manteniendo informada a
comunidad a medida que avanza.
Obtener respaldo oficial
------------------------
Si su trabajo se está realizando en un entorno corporativo — como ocurre
con la mayoría del trabajo en el kernel de Linux — es obvio que debe tener
permiso de los jefes debidamente autorizados antes de poder publicar los
planes o el código de su empresa en una lista de correo pública. La
publicación de código que no ha sido autorizado para su liberación bajo una
licencia compatible con la GPL puede ser especialmente problemática; cuanto
antes la gerencia y el personal legal de una empresa lleguen a un acuerdo
sobre la publicación de un proyecto de desarrollo del kernel, mejor será
para todos los involucrados.
Algunos lectores pueden estar pensando en este momento que su trabajo en el
kernel está destinado a respaldar un producto que aún no ha sido reconocido
oficialmente. Revelar los planes de su empleador en una lista de correo
pública puede no ser una opción viable. En casos como este, vale la pena
considerar si realmente es necesario mantener el secreto; a menudo no hay
una necesidad real de mantener los planes de desarrollo en secreto.
Dicho esto, también hay casos en los que una empresa legítimamente no puede
revelar sus planes al inicio del proceso de desarrollo. Las empresas con
desarrolladores experimentados en el kernel pueden optar por proceder de
manera abierta, bajo el supuesto de que podrán evitar problemas graves de
integración más adelante. Para las empresas sin ese tipo de experiencia
interna, la mejor opción suele ser contratar a un desarrollador externo
para que revise los planes bajo un acuerdo de confidencialidad (NDA). La
Linux Foundation opera un programa de NDA diseñado para ayudar en este tipo
de situaciones; se puede encontrar más información en:
https://www.linuxfoundation.org/nda/
Este tipo de revisión suele ser suficiente para evitar problemas graves más
adelante sin necesidad de revelar públicamente el proyecto.
@@ -0,0 +1,471 @@
.. include:: ../disclaimer-sp.rst
:Original: Documentation/process/4.Coding.rst
:Translator: Carlos Bilbao <carlos.bilbao.osdev@gmail.com> and Avadhut Naik <avadhut.naik@amd.com>
.. _sp_development_coding:
Conseguir el código correcto
============================
Si bien hay mucho que decir a favor de un proceso de diseño sólido y
orientado a la comunidad, la prueba de cualquier proyecto de desarrollo del
kernel está en el código resultante. Es el código lo que será examinado por
otros desarrolladores y lo que será incluido (o no) en el árbol principal.
Por lo tanto, es la calidad de este código lo que determinará el éxito
final del proyecto.
Esta sección examinará el proceso de programación. Comenzaremos observando
algunas de las maneras en que los desarrolladores del kernel pueden cometer
errores. Luego, el enfoque se dirigirá hacia hacer las cosas bien y las
herramientas que pueden ayudar en dicha búsqueda.
Problemas
---------
Estilo de programación
**********************
El kernel ha tenido durante mucho tiempo un estilo de programación
estándar, descrito en la documentación del kernel en
`Documentation/process/coding-style.rst`. Durante gran parte de ese tiempo,
las políticas descritas en ese archivo se tomaban como, en el mejor de los
casos, orientativas. Como resultado, hay una cantidad considerable de
código en el kernel que no cumple con las pautas de estilo de programación.
La presencia de ese código lleva a dos peligros independientes para los
desarrolladores del kernel.
El primero de estos es creer que los estándares de programación del kernel
no importan y no se aplican. La realidad es que agregar nuevo código al
kernel es muy difícil si ese código no está escrito de acuerdo con el
estándar; muchos desarrolladores solicitarán que el código sea reformateado
antes de revisarlo. Una base de código tan grande como el kernel requiere
cierta uniformidad para que los desarrolladores puedan comprender
rápidamente cualquier parte de él. Así que ya no hay lugar para el código
con formato extraño.
Ocasionalmente, el estilo de programación del kernel entrará en conflicto
con el estilo obligatorio de un empleador. En tales casos, el estilo del
kernel tendrá que prevalecer antes de que el código pueda ser fusionado.
Incluir código en el kernel significa renunciar a cierto grado de control
de varias maneras, incluida la forma en que se formatea el código.
La otra trampa es asumir que el código que ya está en el kernel necesita
urgentemente correcciones de estilo de programación. Los desarrolladores
pueden comenzar a generar parches de reformateo como una forma de
familiarizarse con el proceso o como una forma de incluir su nombre en los
registros de cambios del kernel, o ambos. Pero las correcciones puramente
de estilo de programación son vistas como ruido por la comunidad de
desarrollo; tienden a recibir una recepción adversa. Por lo tanto, este
tipo de parche es mejor evitarlo. Es natural corregir el estilo de una
parte del código mientras se trabaja en él por otras razones, pero los
cambios de estilo de programación no deben hacerse por sí mismos.
El documento de estilo de programación tampoco debe leerse como una ley
absoluta que nunca puede transgredirse. Si hay una buena razón para ir en
contra del estilo (una línea que se vuelve mucho menos legible si se divide
para ajustarse al límite de 80 columnas, por ejemplo), perfecto.
Tenga en cuenta que también puedes usar la herramienta `clang-format` para
ayudarle con estas reglas, para reformatear rápidamente partes de su código
automáticamente y para revisar archivos completos a fin de detectar errores
de estilo de programación, errores tipográficos y posibles mejoras. También
es útil para ordenar `#includes`, alinear variables/macros, reformatear
texto y otras tareas similares. Consulte el archivo
`Documentation/dev-tools/clang-format.rst` para más detalles.
Algunas configuraciones básicas del editor, como la indentación y los
finales de línea, se configurarán automáticamente si utilizas un editor
compatible con EditorConfig. Consulte el sitio web oficial de EditorConfig
para obtener más información: https://editorconfig.org/
Capas de abstracción
********************
Los profesores de ciencias de la computación enseñan a los estudiantes a
hacer un uso extensivo de capas de abstracción en nombre de la
flexibilidad y el ocultamiento de la información. Sin duda, el kernel hace
un uso extensivo de la abstracción; ningún proyecto que involucre varios
millones de líneas de código podría sobrevivir de otra manera. Pero la
experiencia ha demostrado que una abstracción excesiva o prematura puede
ser tan perjudicial como la optimización prematura. La abstracción debe
usarse en la medida necesaria y ya.
A un nivel simple, considere una función que tiene un argumento que siempre
se pasa como cero por todos los que la invocan. Uno podría mantener ese
argumento por si alguien eventualmente necesita usar la flexibilidad
adicional que proporciona. Sin embargo, para entonces, es probable que el
código que implementa este argumento adicional se haya roto de alguna
manera sutil que nunca se notó, porque nunca se ha utilizado. O, cuando
surge la necesidad de flexibilidad adicional, no lo hace de una manera que
coincida con la expectativa temprana del programador. Los desarrolladores
del kernel rutinariamente enviarán parches para eliminar argumentos no
utilizados; en general, no deberían añadirse en primer lugar.
Las capas de abstracción que ocultan el acceso al hardware, a menudo para
permitir que la mayor parte de un controlador se utilice con varios
sistemas operativos, son especialmente mal vistas. Dichas capas oscurecen
el código y pueden imponer una penalización en el rendimiento; no
pertenecen al kernel de Linux.
Por otro lado, si se encuentra copiando cantidades significativas de código
de otro subsistema del kernel, es hora de preguntar si, de hecho, tendría
sentido extraer parte de ese código en una biblioteca separada o
implementar esa funcionalidad a un nivel superior. No tiene sentido
replicar el mismo código en todo el kernel.
Uso de #ifdef y del preprocesador en general
********************************************
El preprocesador de C tiene una tentación poderosa para algunos
programadores de C, quienes lo ven como una forma de programar
eficientemente una gran cantidad de flexibilidad en un archivo fuente. Pero
el preprocesador no es C, y el uso intensivo de él da como resultado un
código mucho más difícil de leer para otros y más difícil de verificar por
el compilador para su corrección. El uso intensivo del preprocesador es
asi siempre un signo de un código que necesita algo de limpieza.
La compilación condicional con `#ifdef` es, de hecho, una característica
poderosa, y se usa dentro del kernel. Pero hay poco deseo de ver código que
sté salpicado liberalmente con bloques `#ifdef`. Como regla general, el uso
de `#ifdef` debe limitarse a los archivos de encabezado siempre que sea
posible. El código condicionalmente compilado puede confinarse a funciones
que, si el código no va a estar presente, simplemente se convierten en
vacías. El compilador luego optimizará silenciosamente la llamada a la
función vacía. El resultado es un código mucho más limpio y fácil de
seguir.
Las macros del preprocesador de C presentan varios peligros, incluida la
posible evaluación múltiple de expresiones con efectos secundarios y la
falta de seguridad de tipos. Si te sientes tentado a definir una macro,
considera crear una función en línea en su lugar. El código resultante será
el mismo, pero las funciones en línea son más fáciles de leer, no evalúan
sus argumentos varias veces y permiten que el compilador realice
comprobaciones de tipo en los argumentos y el valor de retorno.
Funciones en línea
******************
Las funciones en línea presentan su propio peligro, sin embargo. Los
programadores pueden enamorarse de la eficiencia percibida al evitar una
llamada a función y llenar un archivo fuente con funciones en línea. Esas
funciones, sin embargo, pueden en realidad reducir el rendimiento. Dado que
su código se replica en cada sitio de llamada, terminan hinchando el tamaño
del kernel compilado. Eso, a su vez, crea presión en las cachés de memoria
del procesador, lo que puede ralentizar la ejecución de manera drástica
Las funciones en línea, como regla, deben ser bastante pequeñas y
relativamente raras. El costo de una llamada a función, después de todo, no
es tan alto; la creación de un gran número de funciones en línea es un
ejemplo clásico de optimización prematura.
En general, los programadores del kernel ignoran los efectos de caché bajo
su propio riesgo. El clásico intercambio de tiempo/espacio que se enseña en
las clases de estructuras de datos iniciales a menudo no se aplica al
hardware contemporáneo. El espacio *es* tiempo, en el sentido de que un
programa más grande se ejecutará más lentamente que uno más compacto.
Los compiladores más recientes toman un papel cada vez más activo al
decidir si una función dada debe realmente ser en línea o no. Por lo tanto,
la colocación liberal de palabras clave "inline" puede no solo ser
excesiva; también podría ser irrelevante.
Bloqueo
*******
En mayo de 2006, la pila de red "Devicescape" fue, con gran fanfarria,
lanzada bajo la licencia GPL y puesta a disposición para su inclusión en el
kernel principal. Esta donación fue una noticia bienvenida; el soporte para
redes inalámbricas en Linux se consideraba, en el mejor de los casos,
deficiente, y la pila de Devicescape ofrecía la promesa de solucionar esa
situación. Sin embargo, este código no fue incluido en el kernel principal
hasta junio de 2007 (versión 2.6.22). ¿Qué sucedió?
Este código mostró varios signos de haber sido desarrollado a puertas
cerradas en una empresa. Pero un problema importante en particular fue que
no estaba diseñado para funcionar en sistemas multiprocesador. Antes de que
esta pila de red (ahora llamada mac80211) pudiera fusionarse, se tuvo que
implementar un esquema de bloqueo en ella.
Hubo un tiempo en que se podía desarrollar código para el kernel de Linux
sin pensar en los problemas de concurrencia que presentan los sistemas
multiprocesador. Ahora, sin embargo, este documento se está escribiendo en
una computadora portátil con dos núcleos. Incluso en sistemas de un solo
procesador, el trabajo que se está realizando para mejorar la capacidad de
respuesta aumentará el nivel de concurrencia dentro del kernel. Los días en
que se podía escribir código para el kernel sin pensar en el bloqueo han
quedado atrás.
Cualquier recurso (estructuras de datos, registros de hardware, etc.) que
pueda ser accedido concurrentemente por más de un hilo debe estar protegido
por un bloqueo. El nuevo código debe escribirse teniendo en cuenta este
requisito; implementar el bloqueo después de que el código ya ha sido
desarrollado es una tarea mucho más difícil. Los desarrolladores del kernel
deben tomarse el tiempo para comprender bien los primitivos de bloqueo
disponibles para elegir la herramienta adecuada para el trabajo. El código
que muestre una falta de atención a la concurrencia tendrá un camino
difícil para ser incluido en el kernel principal.
Regresiones
***********
Un último peligro que vale la pena mencionar es el siguiente: puede ser
tentador realizar un cambio (que puede traer grandes mejoras) que cause un
problema para los usuarios existentes. Este tipo de cambio se llama una
"regresión", y las regresiones se han vuelto muy mal recibidas en el kernel
principal. Con pocas excepciones, los cambios que causan regresiones serán
revertidos si la regresión no se puede solucionar de manera oportuna. Es
mucho mejor evitar la regresión desde el principio.
A menudo se argumenta que una regresión puede justificarse si hace que las
cosas funcionen para más personas de las que crea problemas. ¿Por qué no
hacer un cambio si trae nueva funcionalidad a diez sistemas por cada uno
que rompe? La mejor respuesta a esta pregunta fue expresada por Linus en
julio de 2007 (traducido):
::
Entonces, no arreglamos errores introduciendo nuevos problemas. Eso
lleva a la locura, y nadie sabe si realmente se avanza. ¿Es dos pasos
adelante, uno atrás, o un paso adelante y dos atrás?
(https://lwn.net/Articles/243460/).
Un tipo de regresión especialmente mal recibido es cualquier tipo de cambio
en la ABI del espacio de usuario. Una vez que se ha exportado una interfaz
al espacio de usuario, debe ser soportada indefinidamente. Este hecho hace
que la creación de interfaces para el espacio de usuario sea
particularmente desafiante: dado que no pueden cambiarse de manera
incompatible, deben hacerse bien desde el principio. Por esta razón,
siempre se requiere una gran cantidad de reflexión, documentación clara y
una amplia revisión para las interfaces del espacio de usuario.
Herramientas de verificación de código
**************************************
Por ahora, al menos, escribir código libre de errores sigue siendo un ideal
que pocos de nosotros podemos alcanzar. Sin embargo, lo que podemos esperar
hacer es detectar y corregir tantos de esos errores como sea posible antes
de que nuestro código se integre en el kernel principal. Con ese fin, los
desarrolladores del kernel han reunido una impresionante variedad de
herramientas que pueden detectar una amplia variedad de problemas oscuros
de manera automatizada. Cualquier problema detectado por el ordenador es
un problema que no afectará a un usuario más adelante, por lo que es lógico
que las herramientas automatizadas se utilicen siempre que sea posible.
El primer paso es simplemente prestar atención a las advertencias
producidas por el compilador. Las versiones contemporáneas de gcc pueden
detectar (y advertir sobre) una gran cantidad de errores potenciales. Con
bastante frecuencia, estas advertencias apuntan a problemas reales. El
código enviado para revisión no debería, por regla general, producir
ninguna advertencia del compilador. Al silenciar las advertencias, tenga
cuidado de comprender la causa real e intente evitar "correcciones" que
hagan desaparecer la advertencia sin abordar su causa.
Tenga en cuenta que no todas las advertencias del compilador están
habilitadas de forma predeterminada. Compile el kernel con
"make KCFLAGS=-W" para obtener el conjunto completo.
El kernel proporciona varias opciones de configuración que activan
funciones de depuración; la mayoría de estas se encuentran en el submenú
"kernel hacking". Varias de estas opciones deben estar activadas para
cualquier kernel utilizado para desarrollo o pruebas. En particular,
debería activar:
- FRAME_WARN para obtener advertencias sobre marcos de pila más grandes
que una cantidad determinada. La salida generada puede ser extensa, pero
no es necesario preocuparse por las advertencias de otras partes del
kernel.
- DEBUG_OBJECTS agregará código para rastrear la vida útil de varios
objetos creados por el kernel y advertir cuando se realicen cosas fuera
de orden. Si está agregando un subsistema que crea (y exporta) objetos
complejos propios, considere agregar soporte para la infraestructura de
depuración de objetos.
- DEBUG_SLAB puede encontrar una variedad de errores en la asignación y
uso de memoria; debe usarse en la mayoría de los kernels de desarrollo.
- DEBUG_SPINLOCK, DEBUG_ATOMIC_SLEEP y DEBUG_MUTEXES encontrarán una serie
de errores comunes de bloqueo.
Hay bastantes otras opciones de depuración, algunas de las cuales se
discutirán más adelante. Algunas de ellas tienen un impacto significativo
en el rendimiento y no deben usarse todo el tiempo. Pero dedicar tiempo a
aprender las opciones disponibles probablemente será recompensado muchas
veces en poco tiempo.
Una de las herramientas de depuración más pesadas es el verificador de
bloqueos, o "lockdep". Esta herramienta rastreará la adquisición y
liberación de cada bloqueo (spinlock o mutex) en el sistema, el orden en
que se adquieren los bloqueos en relación entre sí, el entorno actual de
interrupción, y más. Luego, puede asegurarse de que los bloqueos siempre se
adquieran en el mismo orden, que las mismas suposiciones de interrupción se
apliquen en todas las situaciones, y así sucesivamente. En otras palabras,
lockdep puede encontrar varios escenarios en los que el sistema podría, en
raras ocasiones, bloquearse. Este tipo de problema puede ser doloroso
(tanto para desarrolladores como para usuarios) en un sistema desplegado;
lockdep permite encontrarlos de manera automatizada con anticipación. El
código con cualquier tipo de bloqueo no trivial debe ejecutarse con lockdep
habilitado antes de ser enviado para su inclusión.
Como programador diligente del kernel, sin duda alguna, verificará el
estado de retorno de cualquier operación (como una asignación de memoria)
que pueda fallar. Sin embargo, el hecho es que las rutas de recuperación de
fallos resultantes probablemente no hayan sido probadas en absoluto. El
código no probado tiende a ser código roto; podría tener mucha más
confianza en su código si todas esas rutas de manejo de errores se hubieran
ejercitado algunas veces.
El kernel proporciona un marco de inyección de fallos que puede hacer
precisamente eso, especialmente donde están involucradas las asignaciones
de memoria. Con la inyección de fallos habilitada, un porcentaje
configurable de las asignaciones de memoria fallarán; estas fallas pueden
restringirse a un rango específico de código. Ejecutar con la inyección de
fallos habilitada permite al programador ver cómo responde el código cuando
las cosas van mal. Consulte
Documentation/fault-injection/fault-injection.rst para obtener más
información sobre cómo utilizar esta funcionalidad.
Otros tipos de errores se pueden encontrar con la herramienta de análisis
estático "sparse". Con sparse, el programador puede recibir advertencias
sobre confusiones entre direcciones del espacio de usuario y del kernel,
mezcla de cantidades big-endian y little-endian, el paso de valores enteros
donde se espera un conjunto de banderas de bits, y así sucesivamente.
Sparse debe instalarse por separado (puede encontrarse en
https://sparse.wiki.kernel.org/index.php/Main_Page si su distribución no lo
empaqueta); luego, puede ejecutarse en el código agregando "C=1" a su
comando make.
La herramienta "Coccinelle" (https://coccinelle.gitlabpages.inria.fr/website/)
puede encontrar
una amplia variedad de posibles problemas de codificación; también puede
proponer correcciones para esos problemas. Bastantes "parches semánticos"
para el kernel se han empaquetado en el directorio scripts/coccinelle;
ejecutar "make coccicheck" ejecutará esos parches semánticos e informará
sobre cualquier problema encontrado. Consulte:
ref:`Documentation/dev-tools/coccinelle.rst <devtools_coccinelle>` para
obtener más información.
Otros tipos de errores de portabilidad se encuentran mejor compilando su
código para otras arquitecturas. Si no tiene un sistema S/390 o una placa
de desarrollo Blackfin a mano, aún puede realizar el paso de compilación.
Un gran conjunto de compiladores cruzados para sistemas x86 se puede
encontrar en
https://www.kernel.org/pub/tools/crosstool/
Muchos sistemas de compilación disponibles comercialmente también se pueden
utilizar para compilar código de kernel para una amplia gama de
arquitecturas.
Los desarrolladores del kernel son afortunados: tienen acceso a una
variedad de herramientas de verificación de código de la que los
desarrolladores de la mayoría de los otros sistemas pueden estar celosos.
Pero todas esas herramientas no servirán de nada si no las usa. El
resultado final de ignorar estas herramientas es simple: alguien más puede
notificarle de un problema en su código a través de un "oportuno"
comentario en la lista de correo o, peor aún, el código problemático podría
ser eliminado. Es mucho más fácil usar estas herramientas en primer lugar.
Documentación
*************
La documentación a menudo ha sido más la excepción que la regla en el
desarrollo del kernel. Aun así, una documentación adecuada ayudará a
facilitar la integración de nuevo código en el kernel, hará la vida más
fácil a otros desarrolladores, y será útil para sus usuarios. En muchos
casos, la inclusión de documentación se ha vuelto esencialmente
obligatoria.
La primera pieza de documentación para cualquier parche es su changelog
asociado. Las entradas de registro deben describir el problema que se está
esolviendo, la forma de la solución, las personas que trabajaron en el
parche, cualquier efecto relevante en el rendimiento, y cualquier otra cosa
que pueda ser necesaria para entender el parche. Asegúrese de que el
changelog diga *por qué* el parche vale la pena ser aplicado; un
sorprendente número de desarrolladores no proporciona esa información.
Cualquier código que agregue una nueva interfaz para el espacio de usuario,
incluidos los nuevos archivos de sysfs o /proc, debe incluir documentación
de esa interfaz que permita a los desarrolladores del espacio de usuario
saber con qué están trabajando. Consulte `Documentation/ABI/README` para
una descripción de cómo debe formatearse esta documentación y qué
información debe proporcionarse.
El archivo
:ref:`Documentation/admin-guide/kernel-parameters.rst <kernelparameters>`
describe todos los parámetros de arranque del kernel. Cualquier parche que
agregue nuevos parámetros debe agregar las entradas correspondientes a este
archivo.
Cualquier nueva opción de configuración debe ir acompañada de un texto de
ayuda que explique claramente las opciones y cuándo el usuario podría
querer seleccionarlas.
La información de la API interna para muchos subsistemas está documentada
mediante comentarios especialmente formateados; estos comentarios pueden
extraerse y formatearse de diversas maneras mediante el script
"kernel-doc". Si está trabajando dentro de un subsistema que tiene
comentarios de kerneldoc, debe mantenerlos y agregarlos según corresponda
para las funciones disponibles externamente. Incluso en áreas que no han
sido tan documentadas, no hay ningún inconveniente en agregar comentarios
de kerneldoc para el futuro; de hecho, esta puede ser una actividad útil
para desarrolladores de kernel principiantes. El formato de estos
comentarios, junto con alguna información sobre cómo crear plantillas de
kerneldoc, se puede encontrar en
:ref:`Documentation/doc-guide/ <doc_guide>`.
Cualquiera que lea una cantidad significativa de código existente del
kernel notará que, a menudo, los comentarios son notables por su ausencia.
Una vez más, las expectativas para el nuevo código son más altas que en el
pasado; integrar código sin comentarios será más difícil. Dicho esto, hay
poco deseo de tener código excesivamente comentado. El código en sí debe
ser legible, con comentarios que expliquen los aspectos más sutiles.
Ciertas cosas siempre deben comentarse. El uso de barreras de memoria debe
ir acompañado de una línea que explique por qué la barrera es necesaria.
Las reglas de bloqueo para las estructuras de datos generalmente necesitan
explicarse en algún lugar. Las estructuras de datos importantes en general
necesitan documentación completa. Las dependencias no obvias entre
fragmentos de código separados deben señalarse. Cualquier cosa que pueda
tentar a un maintainer de código a hacer una "limpieza" incorrecta necesita
un comentario que explique por qué se hace de esa manera. Y así
sucesivamente.
Cambios en la API interna
*************************
La interfaz binaria proporcionada por el kernel al espacio de usuario no se
puede romper, excepto en las circunstancias más graves. Las interfaces de
programación internas del kernel, en cambio, son altamente fluidas y pueden
cambiarse cuando surge la necesidad. Si usted se encuentra teniendo que
hacer un rodeo alrededor de una API del kernel, o simplemente no utilizando
una funcionalidad específica porque no cumple con sus necesidades, eso
puede ser una señal de que la API necesita cambiar. Como desarrollador del
kernel, usted está autorizado a hacer esos cambios.
Hay, por supuesto, algunas condiciones. Los cambios en la API se pueden
hacer, pero necesitan estar bien justificados. Entonces, cualquier parche
que realice un cambio en la API interna debe ir acompañado de una
descripción de cuál es el cambio y por qué es necesario. Este tipo de
cambio también debe desglosarse en un parche separado, en lugar de estar
enterrado dentro de un parche más grande.
La otra condición es que un desarrollador que cambia una API interna
generalmente está encargado de la tarea de corregir cualquier código dentro
del árbol del kernel que se vea afectado por el cambio. Para una función
ampliamente utilizada, este deber puede llevar a literalmente cientos o
miles de cambios, muchos de los cuales probablemente entren en conflicto
con el trabajo que otros desarrolladores están realizando. No hace falta
decir que esto puede ser un trabajo grande, por lo que es mejor asegurarse
de que la justificación sea sólida. Tenga en cuenta que la herramienta
Coccinelle puede ayudar con los cambios de API a gran escala.
Cuando se realice un cambio incompatible en la API, siempre que sea
posible, se debe asegurar que el código que no ha sido actualizado sea
detectado por el compilador. Esto le ayudará a estar seguro de que ha
encontrado todos los usos en el árbol de esa interfaz. También alertará a
los desarrolladores de código fuera del árbol de que hay un cambio al que
necesitan responder. Apoyar el código fuera del árbol no es algo de lo que
los desarrolladores del kernel deban preocuparse, pero tampoco tenemos que
dificultarles la vida más de lo necesario.
@@ -0,0 +1,391 @@
.. include:: ../disclaimer-sp.rst
:Original: Documentation/process/5.Posting.rst
:Translator: Carlos Bilbao <carlos.bilbao.osdev@gmail.com> and Avadhut Naik <avadhut.naik@amd.com>
.. _sp_development_posting:
Publicación de parches
======================
Tarde o temprano, llega el momento en que su trabajo esté listo para ser
presentado a la comunidad para su revisión y, eventualmente, su inclusión
en el kernel mainline. Como era de esperar, la comunidad de desarrollo del
kernel ha desarrollado un conjunto de convenciones y procedimientos que se
utilizan en la publicación de parches; seguirlos hará la vida mucho más
fácil para todos los involucrados. Este documento intentará cubrir estas
expectativas con un detalle razonable; también se puede encontrar más
información en los archivos.
:ref:`Documentation/translations/sp_SP/process/submitting-patches.rst <sp_submittingpatches>`
and :ref:`Documentation/translations/sp_SP/process/submit-checklist.rst <sp_submitchecklist>`
Cuando publicar
---------------
Hay una tentación constante de evitar publicar parches antes de que
estén completamente “listos”. Para parches simples, eso no es un
problema. Sin embargo, si el trabajo que se está realizando es complejo,
hay mucho que ganar al obtener comentarios de la comunidad antes de que
se complete el trabajo. Por lo tanto, se debería considerar publicar
trabajo en progreso, o incluso poner a disposición un árbol de git para
que los desarrolladores interesados puedan ponerse al día con su trabajo
en cualquier momento.
Al publicar código que aún no se considera listo para su inclusión, es
una buena idea decirlo en la propia publicación. Además, mencione
cualquier trabajo importante que aún falte por hacer y cualquier problema
conocido. Menos personas mirarán los parches que se sabe que están a
medias, pero aquellos que lo hagan vendrán con la idea de que pueden
ayudarlo a llevar el trabajo en la dirección correcta.
Antes de crear parches
----------------------
Se deben hacer varias cosas antes de considerar enviar parches a la
comunidad de desarrollo. Estas incluyen:
- Pruebe el código en la medida de lo posible. Utilice las herramientas
de depuración del kernel, asegúrese de que el kernel se compilará con
todas las combinaciones razonables de opciones de configuración, use
compiladores cruzados para compilar para diferentes arquitecturas, etc.
- Asegúrese de que su código cumpla con las directrices de estilo de
codificación del kernel.
- ¿Su cambio tiene implicaciones de rendimiento? Si es así, debe ejecutar
puntos de referencia que muestren cuál es el impacto (o beneficio) de
su cambio; se debe incluir un resumen de los resultados con el parche.
- Asegúrese de que tiene derecho a publicar el código. Si este trabajo
se realizó para un empleador, es probable que el empleador tenga
derecho al trabajo y debe estar de acuerdo con su lanzamiento bajo la
GPL.
Como regla general, pensar un poco más antes de publicar el código casi
siempre compensa el esfuerzo en poco tiempo.
Preparación del parche
----------------------
La preparación de parches para su publicación puede ser una cantidad
sorprendente de trabajo, pero, una vez más, intentar ahorrar tiempo aquí
generalmente no es recomendable, ni siquiera a corto plazo.
Los parches deben prepararse contra una versión específica del kernel.
Como regla general, un parche debe basarse en el mainline actual que se
encuentra en el árbol git de Linus. Al basarse en el mainline, comience
con un punto de lanzamiento bien conocido, una versión estable o -rc, en
lugar de bifurcarse fuera del mainline en un punto arbitrario.
Puede ser necesario hacer revisiones contra -mm, linux-next o un árbol de
subsistemas para facilitar pruebas y revisiones más amplias. Dependiendo
del área de su parche y de lo que esté sucediendo en otros lugares, basar
un parche en estos otros árboles puede requerir una cantidad significativa
de trabajo para resolver conflictos y lidiar con los cambios de API.
Solo los cambios más simples deben formatearse como un solo parche; todo
lo demás debe hacerse como una serie lógica de cambios. Dividir parches
es un poco un arte; algunos desarrolladores pasan mucho tiempo averiguando
cómo hacerlo de la manera que la comunidad espera. Sin embargo, hay
algunas reglas generales que pueden ayudar considerablemente:
- La serie de parches que publique casi seguramente no será la serie de
cambios que se encuentran en su sistema de control de revisiones. En su
lugar, los cambios que ha realizado deben considerarse en su forma
final y luego dividirse de manera que tengan sentido. A los
desarrolladores les interesan los cambios discretos y autónomos, no el
camino que tomó para llegar a esos cambios.
- Cada cambio lógicamente independiente debe formatearse como un parche
separado. Estos cambios pueden ser pequeños (“agregar un campo a esta
estructura”) o grandes (agregar un nuevo controlador significativo,
por ejemplo), pero deben ser conceptualmente pequeños y susceptibles
de una descripción de una línea. Cada parche debe hacer un cambio
especifico que pueda ser revisado por sí mismo y verificado para hacer
lo que dice que hace.
- Para reafirmar la pauta anterior: no mezcle diferentes tipos de cambios
en el mismo parche. Si un solo parche corrige un error de seguridad
crítico, reorganiza algunas estructuras y reformatea el código, es muy
probable que se pase por alto y se pierda la solución importante.
- Cada parche debe producir un kernel que se compile y funcione
correctamente; si su serie de parches se interrumpe en el medio, el
resultado debería seguir siendo un kernel funcional. La aplicación
parcial de una serie de parches es un escenario común cuando se
utiliza la herramienta “git bisect” para encontrar regresiones; si
el resultado es un kernel roto, hará la vida más difícil para los
desarrolladores y usuarios que participan en el noble trabajo de
rastrear problemas.
- Sin embargo, no lo exagere. Un desarrollador una vez publicó un conjunto
de ediciones en un solo archivo como 500 parches separados – un acto
que no lo convirtió en la persona más popular en la lista de correo del
kernel. Un solo parche puede ser razonablemente grande si todavía
contiene un solo cambio *lógico*.
- Puede ser tentador agregar una infraestructura completamente nueva con
una serie de parches, pero dejar esa infraestructura sin usar hasta el
parche final de la serie lo habilite todo. Esta tentación debe evitarse
si es posible; si esa serie agrega regresiones, bisection señalará el
ultimo parche como el que causó el problema, aunque el error real esté
en otra parte. Siempre que sea posible, un parche que agregue código
nuevo debe hacer que ese código se active de inmediato.
Trabajar para crear la serie de parches perfecta puede ser un proceso
frustrante que lleva mucho tiempo y reflexión después de que el “trabajo
real” se ha hecho. Sin embargo, cuando se hace correctamente, es un tiempo
bien empleado.
Formato de parches y registros de cambios
-----------------------------------------
Así que ahora tiene una serie perfecta de parches para publicar, pero el
trabajo aún no se ha hecho. Cada parche necesita ser formateado en un
mensaje que comunique rápida y claramente su propósito al resto del
mundo. A tal fin, cada parche se compondrá de lo siguiente:
- Una línea opcional “From” que nombra al autor del parche. Esta línea
solo es necesaria si pasa el parche de otra persona por correo
electrónico, pero nunca está de más agregarla en caso de duda.
- Una descripción de una línea de lo que hace el parche. Este mensaje
debería ser suficiente para que un lector que lo vea sin otro contexto
pueda entender el alcance del parche; la línea aparecerá en los
registros de cambios de “forma corta”. Este mensaje generalmente se
formatea con el nombre del subsistema relevante primero, seguido del
propósito del parche. Por ejemplo:
::
gpio: fix build on CONFIG_GPIO_SYSFS=n
- Una línea en blanco seguida de una descripción detallada del contenido
del parche. Esta descripción puede ser tan larga como sea necesario;
debería decir qué hace el parche y por qué debe aplicarse al kernel.
- Una o más líneas de etiquetas, con, como mínimo, una línea
Signed-off-by: del autor del parche. Las etiquetas se describirán con
más detalle a continuación.
Los elementos de arriba, juntos, forman el registro de cambios para el
parche. Escribir buenos registros de cambios es un arte crucial, pero a
menudo descuidado; vale la pena pasar otro momento discutiendo este tema.
Al escribir un registro de cambios, debe recordar que muchas personas
diferentes leerán sus palabras. Estos incluyen a los maintainers y
revisores de subsistemas que necesitan decidir si el parche debe
incluirse, a los distribuidores y otros maintainers que intentan
determinar si un parche debe ser “backported” a otros kernels, a los
cazadores de errores que se preguntan si el parche es responsable de un
problema que están persiguiendo, a los usuarios que quieren saber cómo
ha cambiado el kernel, y más. Un buen registro de cambios transmite la
información necesaria a todas estas personas de la forma más directa y
concisa posible.
Con ese fin, la línea de resumen debe describir los efectos y la
motivación del cambio, así como lo mejor posible dada la restricción de
una línea. La descripción detallada puede ampliar esos temas y
proporcionar cualquier información adicional necesaria. Si el parche
corrige un error, cita el commit que introdujo el error si es posible (y
por favor, proporcione tanto el ID del commit como el título al citar
commits). Si un problema está asociado con un registro específico o la
salida del compilador, incluya esa salida para ayudar a otros usuarios a
buscar una solución al mismo problema. Si el cambio está destinado a
apoyar otros cambios que llegarán en un parche posterior, dígalo. Si se
cambian las API internas, detalle esos cambios y cómo deben responder
otros desarrolladores. En general, cuanto más pueda ponerse en los zapatos
de todos los que leerán su registro de cambios, mejor será ese registro de
cambios (y el kernel en su conjunto).
No hace falta decir que el registro de cambios debe ser el texto utilizado
al realizar el commit en un sistema de control de revisiones. Será seguido
por:
- El parche, en el formato unificado de parche (“-u”). Usar la opción
“-p” en diff asociará los nombres de las funciones con los cambios, lo
que hará que el parche resultante sea más fácil de leer para otros.
Debe evitar incluir cambios en archivos irrelevantes (los generados por
el proceso de compilación, por ejemplo, o los archivos de respaldo del
editor) en el parche. El archivo “dontdiff” en el directorio de
Documentation puede ayudar en este sentido; páselo a diff con la
opción “-X”.
Las etiquetas ya mencionadas brevemente anteriormente proporcionan
información sobre cómo surgió el parche. Se describen en detalle en el
documento
:ref:`Documentation/translations/sp_SP/process/submitting-patches.rst <sp_submittingpatches>`;
lo que sigue aquí es un breve resumen.
Una etiqueta se usa para referirse a commits anteriores que introdujeron
problemas corregidos por el parche::
Fixes: 1f2e3d4c5b6a ("La primera línea del commit especificada por los primeros 12 caracteres de su ID SHA-1.")
Otra etiqueta se utiliza para vincular páginas web con información
adicional o detalles, por ejemplo, una discusión previa que condujo al
parche o un documento con una especificación implementada por el parche::
Link: https://example.com/somewhere.html otras cosas opcionales
Muchos maintainers, al aplicar un parche, también agregan esta etiqueta
para vincular a la última publicación de revisión pública del parche; a
menudo, eso se hace automáticamente mediante herramientas como b4 o git
hook como el que se describe en
'Documentation/maintainer/configure-git.rst'.
Si la URL apunta a un informe de error público que está siendo corregido
por el parche, use la etiqueta “Closes:” (Cierra) en su lugar::
Closes: https://example.com/issues/1234 otras cosas opcionales
Algunos rastreadores de errores tienen la capacidad de cerrar problemas
automáticamente cuando se aplica un commit con tal etiqueta. Algunos bots
que monitorean listas de correo también pueden rastrear dichas etiquetas
y realizar ciertas acciones. Los rastreadores de errores privados y las
URL no válidas están prohibidos.
Otro tipo de etiqueta se utiliza para documentar quién estuvo involucrado
en el desarrollo del parche. Cada uno de estos utiliza este formato::
tag: Full Name <email address> otras cosas opcionales
Las etiquetas de uso común son:
- Signed-off-by: esta es una certificación del desarrollador de que él
o ella tiene el derecho de enviar el parche para su inclusión en el
kernel. Es un acuerdo con el Certificado de Origen del Desarrollador,
que se encuentra en
:ref:`Documentation/translations/sp_SP/process/submitting-patches.rst <sp_submittingpatches>`.
El código sin la firma adecuada no se puede fusionar en el mainline.
- Co-developed-by: indica que el parche fue co-creado por varios
desarrolladores; se utiliza para atribuir a los coautores (además del
autor atribuido por la etiqueta From:) cuando varias personas trabajan
en un solo parche. Cada Co-developed-by: debe ir seguido inmediatamente
por un Signedoff-by: del coautor asociado. Los detalles y ejemplos se
pueden encontrar en
:ref:`Documentation/translations/sp_SP/process/submitting-patches.rst <sp_submittingpatches>`.
- Acked-by: indica un acuerdo por parte de otro desarrollador (a menudo
un maintainer del código relevante) de que el parche es apropiado para
su inclusión en el kernel.
- Tested-by: indica que la persona nombrada ha probado el parche y ha
encontrado que funciona.
- Reviewed-by: el desarrollador nombrado ha revisado el parche para
verificar que sea correcto; consulte la declaración del revisor en
:ref:`Documentation/translations/sp_SP/process/submitting-patches.rst <sp_submittingpatches>`
para obtener más detalles.
- Reported-by: nombra a un usuario que informó un problema que se
soluciona con este parche; esta etiqueta se utiliza para dar crédito
a las personas (a menudo infravalorada) que prueban nuestro código y
nos hacen saber cuándo las cosas no funcionan correctamente. Tenga en
cuenta que esta etiqueta debe ir seguida de una etiqueta Closes: que
apunte al informe, a menos que el informe no esté disponible en la
web. La etiqueta Link: se puede usar en lugar de Closes: si el parche
corrige una parte de los problemas reportados.
- Cc: la persona nombrada recibió una copia del parche y tuvo la
oportunidad de comentar sobre él.
Tenga cuidado al agregar etiquetas a sus parches, ya que solo Cc: es
apropiado para la adición sin el permiso explícito de la persona nombrada;
usar Reported-by: está casi bien en su mayoría, pero pida permiso si el
error fue reportado en privado.
Envió del parche
----------------
Antes de enviar sus parches por correo, hay un par de cosas más de las
que debe ocuparse:
- ¿Está seguro de que su correo no corromperá los parches? Los parches
con cambios gratuitos de espacio en blanco o ajuste de línea
realizados por el cliente de correo no se aplicarán en el otro
extremo, y a menudo, no se examinarán en detalle. Si tiene alguna
duda, envíese el parche por correo y convénzase de que parece
intacto.
:ref:`Documentation/translations/sp_SP/process/email-clients.rst <sp_email_clients>`
tiene algunos consejos útiles sobre cómo hacer que clientes de correo
específicos funcionen para enviar parches.
- ¿Está seguro de que su parche está libre de errores tontos? Siempre
debe ejecutar parches a través de scripts/checkpatch.pl y abordar las
quejas que surjan. Por favor, tenga en cuenta que checkpatch.pl, aunque
es la encarnación de una buena cantidad de pensamiento sobre cómo
deberían ser los parches del kernel, no es más inteligente que usted.
Si corregir una queja de checkpatch.pl empeoraría el código, no lo
haga.
Los parches siempre deben enviarse como texto sin formato. Por favor, no
los envíe como archivos adjuntos; eso hace que sea mucho más difícil para
los revisores citar secciones del parche en sus respuestas. En su lugar,
simplemente coloca el parche directamente en su mensaje.
Al enviar parches por correo, es importante enviar copias a cualquier
persona que pueda estar interesada en ellos. A diferencia de otros
proyectos, el kernel anima a la gente a equivocarse por el lado de enviar
demasiadas copias; no asuma que las personas relevantes verán su
publicación en las listas de correo. En particular, las copias deben
ir a:
- El (los) maintainer(s) del (de los) subsistema(s) afectado(s). Como se
describió anteriormente, el archivo MAINTAINERS es el primer lugar para
buscar a estas personas.
- Otros desarrolladores que han estado trabajando en la misma
área – especialmente aquellos que podrían estar trabajando allí ahora.
Usar git para ver quién más ha modificado los archivos en los que está
trabajando puede ser útil.
- Si está respondiendo a un informe de error o a una solicitud de
función, copie también al autor.
- Envié una copia a la lista de correo relevante o, si no se aplica nada
más, a la lista de linux-kernel.
- Si está corrigiendo un error, piense si la corrección debe incluirse en
la próxima actualización estable. Si es así, stable@vger.kernel.org
debería obtener una copia del parche. También agregue un
"Cc: stable@vger.kernel.org" a las etiquetas dentro del parche; eso
hará que el equipo estable reciba una notificación cuando su solución
incluya en el mainline.
Al seleccionar destinatarios para un parche, es bueno saber quién cree que
eventualmente aceptará el parche y lo fusionará. Aunque es posible enviar
parches directamente a Linus Torvalds y hacer que los fusione, las cosas
normalmente no se hacen de esa manera. Linus está ocupado y hay
maintainers de subsistemas que vigilan partes específicas del kernel.
Generalmente, querrá que ese maintainer fusione sus parches. Andrew Morton
es a menudo el objetivo del parche de último recurso si no hay un
maintainer obvio.
Los parches necesitan buenas líneas de asunto. El formato canónico de una
línea de parche es algo así como:
::
[PATCH nn/mm] subsys: descripción en una línea del parche
donde “nn” es el número ordinal del parche, “”mm” es el número total de
parches en la serie, y “subsys” es el nombre del subsistema afectado.
Claramente, nn/mm se puede omitir para un parche único e independiente.
Si tiene una serie significativa de parches, es costumbre enviar una
descripción introductoria como parte cero. Sin embargo, esta convención no
se sigue universalmente; si la utiliza, recuerde que la información en la
introducción no se incluye en los registros de cambios del kernel. Por lo
tanto, asegúrese de que los parches, en sí mismos, tengan información
completa del registro de cambios.
En general, la segunda y las siguientes partes de un parche de varias
partes deben enviarse como una respuesta a la primera parte para que todas
se hilen juntas en el extremo receptor. Herramientas como git y quilt
tienen comandos para enviar por correo un conjunto de parches con el
subproceso adecuado. Sin embargo, si tiene una serie larga y está usando
git, por favor evite la opción –chain-reply-to para evitar crear un
anidamiento excepcionalmente profundo.
@@ -0,0 +1,230 @@
.. include:: ../disclaimer-sp.rst
:Original: Documentation/process/6.Followthrough.rst
:Translator: Carlos Bilbao <carlos.bilbao.osdev@gmail.com> and Avadhut Naik <avadhut.naik@amd.com>
.. _sp_development_followthrough:
Seguimiento
===========
Llegados a este punto, ha seguido las directrices dadas hasta ahora, lo que
sumado a sus propias habilidades de ingeniería, ha resultado en una serie
de parches perfectos. Uno de los mayores errores que incluso los
desarrolladores de kernel experimentados pueden cometer es concluir que su
trabajo ya está hecho. En verdad, publicar parches indica una transición a
la siguiente etapa del proceso, con, posiblemente, bastante trabajo aún por
hacer.
Es raro un parche que sea tan bueno en su primera publicación que no haya
espacio para la mejora. El proceso de desarrollo del kernel reconoce este
hecho y, como resultado, está muy orientado hacia la mejora del código
publicado. Y usted, como autor de ese código, se espera que trabaje con la
comunidad del kernel para asegurarse de que su código esté a la altura de
los estándares de calidad del kernel. No participar en este proceso es muy
probable que impida la inclusión de sus parches en la línea principal.
Trabajando con revisores
------------------------
Un parche de cualquier importancia resultará en una serie de comentarios de
otros desarrolladores a medida que revisan el código. Trabajar con los
revisores puede ser, para muchos desarrolladores, la parte más intimidante
del proceso de desarrollo del kernel. Sin embargo, la vida puede ser mucho
más fácil si tiene en cuenta algunas cosas:
- Si ha explicado bien su parche, los revisores entenderán su valor y por
qué se tomó la molestia de escribirlo. Pero ese valor no les impedirá
hacer una pregunta fundamental: ¿cómo será mantener un kernel con este
código en él cinco o diez años después? Muchos de los cambios que se le
pueden pedir que haga, desde ajustes de estilo de codificación hasta
reescrituras sustanciales, provienen de la comprensión de que Linux
seguirá existiendo y en desarrollo dentro de una década.
- La revisión de código es un trabajo arduo y es una ocupación
relativamente ingrata; la gente recuerda quién escribió el código del
kernel, pero hay poca fama duradera para aquellos que lo revisaron. Así
que los revisores pueden ponerse de mal humor, especialmente cuando ven
los mismos errores repetirse una y otra vez. Si recibe una revisión que
parece enojada, insultante o abiertamente ofensiva, resista el impulso de
responder de la misma manera. La revisión de código se trata del código,
no de las personas, y los revisores de código no lo están atacando
personalmente.
- De manera similar, los revisores de código no están tratando de promover
las agendas de sus empleadores a expensas de la suya. Los desarrolladores
del kernel a menudo esperan estar trabajando en el kernel dentro de
varios años, pero entienden que su empleador podría cambiar.
Verdaderamente, casi sin excepción, están trabajando hacia la creación
del mejor kernel posible; no están tratando de causar incomodidad a los
competidores de sus empleadores.
- Esté preparado para solicitudes aparentemente ridículas de cambios en el
estilo de codificación y solicitudes para factorizar parte de su código
en partes compartidas del kernel. Una de las tareas que realizan los
maintainers es mantener las cosas con una apariencia uniforme. A veces, esto significa que el truco ingenioso en su driver para sortear un problema necesita convertirse en una característica generalizada del kernel lista para la próxima vez.
En resumen, cuando los revisores le envían comentarios, necesita prestar
atención a las observaciones técnicas que están haciendo. No permita que su
forma de expresarse o su propio orgullo le impidan hacerlo. Cuando reciba
comentarios de revisión sobre un parche, tómese el tiempo para entender lo
que el revisor está tratando de decir. Si es posible, arregle las cosas que
el revisor le está pidiendo que corrija. Y responda al revisor:
agradézcales y describa cómo responderá a sus preguntas.
Tenga en cuenta que no tiene que estar de acuerdo con cada cambio sugerido
por los revisores. Si cree que el revisor ha malinterpretado su código,
explique lo que realmente está sucediendo. Si tiene una objeción técnica a
un cambio sugerido, descríbalo y justifique su solución al problema. Si sus
explicaciones tienen sentido, el revisor las aceptará. Sin embargo, si su
explicación no resulta persuasiva, especialmente si otros comienzan a estar
de acuerdo con el revisor, tómese un tiempo para reflexionar nuevamente
sobre las cosas. Puede ser fácil quedar cegado por su propia solución a un
problema hasta el punto de no darse cuenta de que algo está
fundamentalmente mal o, quizás, ni siquiera está resolviendo el problema
correcto.
Andrew Morton ha sugerido que cada comentario de revisión que no resulte en
un cambio de código debería resultar en un comentario adicional en el
código; eso puede ayudar a los revisores futuros a evitar las preguntas que
surgieron la primera vez.
Un error fatal es ignorar los comentarios de revisión con la esperanza de
que desaparezcan. No desaparecerán. Si vuelve a publicar código sin haber
respondido a los comentarios que recibió la vez anterior, es probable que
descubra que sus parches no van a ninguna parte.
Hablando de volver a publicar código: tenga en cuenta que los revisores no
recordarán todos los detalles del código que publicó la vez anterior. Así
que siempre es una buena idea recordarles sobre problemas planteados
anteriormente y cómo los manejó; el registro de cambios del parche es un
buen lugar para este tipo de información. Los revisores no deberían tener
que buscar en los archivos de la lista para familiarizarse con lo que se
dijo la última vez; si les ayuda a tener un buen comienzo, estarán de mejor
humor cuando revisiten su código.
¿Qué sucede si ha intentado hacer todo bien y las cosas aún no van a
ninguna parte? La mayoría de los desacuerdos técnicos pueden resolverse
mediante discusión, pero hay momentos en los que alguien simplemente tiene
que tomar una decisión. Si realmente cree que esta decisión está en su
contra de manera incorrecta, siempre puede intentar apelar a una autoridad
superior. En el momento de escribir esto, esa autoridad superior tiende a
ser Andrew Morton. Andrew tiene un gran respeto en la comunidad de
desarrollo del kernel; a menudo puede desbloquear una situación que parece
estar irremediablemente bloqueada. Sin embargo, apelar a Andrew no debe
hacerse a la ligera, y no antes de que se hayan explorado todas las demás
alternativas. Y tenga en cuenta, por supuesto, que él puede no estar de
acuerdo con usted tampoco.
¿Qué pasa después?
--------------------
Si un parche se considera algo bueno para agregar al kernel, y una vez que
se hayan resuelto la mayoría de los problemas de revisión, el siguiente
paso suele ser la entrada en el árbol del mantenedor de un subsistema. Cómo
funciona eso varía de un subsistema a otro; cada mantenedor tiene su propia
forma de hacer las cosas. En particular, puede haber más de un árbol, uno,
quizás, dedicado a los parches planificados para la próxima ventana de
fusión y otro para trabajos a más largo plazo.
Para los parches que se aplican a áreas para las que no hay un árbol de
subsistema obvio (parches de gestión de memoria, por ejemplo), el árbol
predeterminado suele ser -mm. Los parches que afectan a múltiples
subsistemas también pueden terminar pasando por el árbol -mm.
La inclusión en un árbol de subsistema puede dar mayor visibilidad a un
parche. Ahora, otros desarrolladores que trabajan con ese árbol recibirán
el parche por defecto. Los árboles de subsistemas típicamente alimentan
linux-next también, haciendo que su contenido sea visible para la comunidad
de desarrollo en su conjunto. En este punto, hay una buena probabilidad de
que reciba más comentarios de un nuevo conjunto de revisores; estos
comentarios necesitan ser respondidos como en la ronda anterior.
Lo que también puede suceder en este punto, dependiendo de la naturaleza de
su parche, es que aparezcan conflictos con el trabajo que están realizando
otros. En el peor de los casos, conflictos pesados de parches pueden
resultar en que algunos trabajos se pongan en espera para que los parches
restantes puedan ser ajustados y fusionados. Otras veces, la resolución de
conflictos involucrará trabajar con otros desarrolladores y, posiblemente,
mover algunos parches entre árboles para asegurarse de que todo se aplique
sin problemas. Este trabajo puede ser un dolor, pero cuente sus
bendiciones: antes de la llegada del árbol linux-next, estos conflictos a
menudo solo surgían durante la ventana de fusión y tenían que ser abordados
de prisa. Ahora pueden resolverse con calma, antes de que se abra la
ventana de fusión (merge window).
Algún día, si todo va bien, iniciará sesión y verá que su parche ha sido
incluido en el kernel principal. ¡Felicidades! Una vez que la celebración
termine (y se hayas agregado al archivo MAINTAINERS), vale la pena
recordar un pequeño hecho importante: el trabajo aún no está hecho. La
inclusión trae sus propios desafíos.
Para empezar, la visibilidad de su parche ha aumentado una vez más. Puede
haber una nueva ronda de comentarios de desarrolladores que no estaban al
tanto del parche antes. Puede ser tentador ignorarlos, ya que ya no hay
cuestión de que su código sea fusionado. Sin embargo, resista esa
tentación; aún necesita ser receptivo a los desarrolladores que tienen
preguntas o sugerencias.
Más importante aún, la inclusión en la línea principal pone su código en
manos de un grupo mucho más grande de probadores. Incluso si ha contribuido
un driver para hardware que aún no está disponible, se sorprenderá de
cuántas personas construirán su código en sus kernels. Y, por supuesto,
donde hay probadores, habrá informes de errores.
El peor tipo de informes de errores son las regresiones. Si su parche causa
una regresión, encontrará un número incómodo de ojos sobre usted; las
regresiones pueden dar lugar a mucho malestar en la comunidad y pueden
hacer que algunos desarrolladores comiencen a preguntarse si su parche
realmente debería haber sido fusionado en primer lugar. Así que esté atento
a los comentarios sobre problemas y, si es posible, corrija los errores de
inmediato.
Después de haber abordado cualquier regresión, puede haber otros errores
ordinarios que resolver. El período de estabilización es su mejor
oportunidad para corregir estos errores y garantizar que el debut de su
código en una versión del kernel principal sea lo más sólido posible. Así
que, por favor, responda a los informes de errores y solucione los
problemas si es posible. Para eso es el período de estabilización; puede
comenzar a crear parches nuevos y geniales una vez que se hayan resuelto
los problemas de los antiguos.
Y no olvide que hay otros hitos que también pueden generar informes de
errores: la próxima versión estable del kernel principal, cuando
distribuidores prominentes adopten una versión del kernel que contenga su
parche, etc. Continuar respondiendo a estos informes es una cuestión de
orgullo básico en su trabajo. Sin embargo, si eso no es suficiente
motivación, también vale la pena considerar que la comunidad de desarrollo
recuerda a los desarrolladores que pierden interés en su código después de
que se fusiona. La próxima vez que publique un parche, lo evaluarán con la
suposición de que no estará disponible para mantenerlo después.
Otras cosas que pueden suceder
-------------------------------
Un día, puede que abra su cliente de correo y vea que alguien le ha enviado
un parche para su código. Esa es una de las ventajas de tener su código
disponible públicamente, después de todo. Si está de acuerdo con el parche, puede reenviarlo al maintainer del subsistema (asegúrese de incluir una
línea From: adecuada para que la atribución sea correcta, y añada su propia
firma), o enviar una respuesta Acked-by: y dejar que el autor original lo
envíe hacia arriba.
Si no está de acuerdo con el parche, envíe una respuesta educada explicando
por qué. Si es posible, dígale al autor qué cambios deben hacerse para que
considere el parche aceptable. Existe una cierta resistencia a incluir
parches que son rechazados por el autor y el maintainer del código, pero
esto tiene un límite. Si se interpreta que bloque buen trabajo, esos
parches eventualmente lo eludirán y se incorporarán al kernel de todos
modos. En el kernel de Linux, nadie tiene poder de veto absoluto sobre
ningún código. Excepto quizás Linus.
En muy raras ocasiones, puede encontrar algo completamente diferente: otro
desarrollador publica una solución distinta a su problema. En ese punto, es
probable que uno de los dos parches no se incluya, y "el mío fue el
primero" no se considera un argumento técnico convincente. Si el parche de
otra persona desplaza al suyo y se incorpora al kernel, realmente solo hay
una manera de responder: alegrarse de que su problema se haya resuelto y
continuar con su trabajo. Que su trabajo sea desplazado de esta manera
puede ser doloroso y desalentador, pero la comunidad recordará su reacción
mucho después de que hayan olvidado de quién era el parche que realmente se
incluyó.
@@ -0,0 +1,214 @@
.. include:: ../disclaimer-sp.rst
:Original: Documentation/process/7.AdvancedTopics.rst
:Translator: Carlos Bilbao <carlos.bilbao.osdev@gmail.com> and Avadhut Naik <avadhut.naik@amd.com>
.. _sp_development_advancedtopics:
Temas avanzados
===============
Llegados a este punto, con suerte, tiene una idea de cómo funciona el
proceso de desarrollo. Sin embargo, ¡todavía hay más que aprender! Esta
sección cubrirá varios temas que pueden ser útiles para los desarrolladores
que desean convertirse en una parte regular del proceso de desarrollo del
kernel Linux.
Gestionar parches con git
-------------------------
El uso del control de versiones distribuido para el kernel comenzó a
principios de 2002 cuando Linus comenzó a jugar con la aplicación
propietaria BitKeeper. Aunque BitKeeper fue controvertido, el enfoque de
la gestión de versiones de software que incorporó ciertamente no lo fue.
El control de versiones distribuido permitió una aceleración inmediata
del proyecto de desarrollo del kernel. En los tiempos actuales, existen
varias alternativas gratuitas a BitKeeper. Para bien o para mal, el
proyecto del kernel ha optado por git como su herramienta preferida.
Administrar parches con git puede hacer la vida mucho más fácil para el
desarrollador, especialmente a medida que crece el volumen de esos
parches. Git también tiene sus asperezas y representa ciertos peligros;
es una herramienta joven y poderosa que aún está siendo civilizada por
sus desarrolladores. Este documento no intentará enseñar al lector cómo
usar git; eso sería material suficiente para un documento extenso por
derecho propio. En su lugar, el enfoque aquí será cómo git encaja en el
proceso de desarrollo del kernel en particular. Los desarrolladores que
deseen ponerse al día con git encontrarán más información en:
https://git-scm.com/
https://www.kernel.org/pub/software/scm/git/docs/user-manual.html
y en varios tutoriales que se encuentran en la web.
El primer orden del negocio es leer los sitios mencionados anteriormente
y comprender cómo funciona git antes de intentar usarlo para poner
parches a disposición de otros. Un desarrollador que usa git debe ser
capaz de obtener una copia del repositorio mainline, explorar el historial
de revisiones, hacer commits en el árbol, usar ramas, etcétera. También es
útil entender las herramientas de git para rescribir la historia (como
rebase). Git viene con su propia terminología y conceptos; un nuevo
usuario de git debe conocer las referencias, las ramas remotas, el índice,
las fusiones fast-forward, los pushes y pulls, las cabezas separadas,
etcétera. Todo puede ser un poco intimidante al principio, pero los
conceptos no son tan difíciles de entender con un poco de estudio.
Usar git para generar parches para enviarlos por correo electrónico puede
ser un buen ejercicio mientras te pones al día.
Cuando esté listo para comenzar a publicar árboles de git para que otros
los vean, necesitará por supuesto, un servidor del que se pueda extraer.
Configurar un servidor de este tipo con git-daemon es relativamente
sencillo si tiene un sistema accesible a Internet. De lo contrario, los
sitios de alojamiento público y gratuitos (GitHub, por ejemplo) están
comenzando a aparecer en la red. Los desarrolladores establecidos pueden
obtener una cuenta en kernel.org, pero no son fáciles de conseguir; ver
https://kernel.org/faq/ para más información.
El flujo de trabajo normal de git implica el uso de muchas ramas. Cada
línea de desarrollo puede separarse en una “rama temática” separada y
mantenerse de forma independiente. Las ramas en git son baratas, no hay
razón para no hacer uso gratuito de ellas. Y, en cualquier caso, no debe
desarrollarse en ninguna rama de la que tenga la intención de pedir a
otros que hagan un pull. Las ramas disponibles públicamente deben crearse
con cuidado; fusione los parches de las ramas de desarrollo cuando estén
en forma completa y listos para usar – no antes.
Git proporciona herramientas poderosas que permiten reescribir su historia
de desarrollo. Un parche inconveniente (uno que rompe la bisección, por
ejemplo, o que tiene algún otro tipo de error obvio) se puede corregir en
su lugar o hacer que desaparezca de la historia por completo. Una serie de
parches se puede reescribir como si se hubiera escrito sobre el mainline
de hoy, aunque haya estado trabajando en ella durante meses. Los cambios
se pueden transferir de manera transparente de una rama a otra. Y así
sucesivamente. El uso juicioso de la capacidad de git para revisar el
historial puede ayudar en la creación de conjuntos de parches limpios con
menos problemas.
El uso excesivo de esta capacidad puede llevar a otros problemas más allá
de una simple obsesión por crear la historia perfecta del proyecto.
Reescribir la historia rescribirá los cambios contenidos en esa historia,
convirtiendo un árbol del kernel probado (con suerte) en uno no probado.
Pero más allá de eso, los desarrolladores no pueden colaborar fácilmente
si no tienen una vista compartida del historial del proyecto; si reescribe
la historia que otros desarrolladores han introducido en sus repositorios,
les hará la vida mucho más difícil a esos desarrolladores. Por lo tanto,
aquí se aplica una regla simple general: la historia que se ha exportado
a otros generalmente debe considerarse inmutable a partir de entonces.
Por lo tanto, una vez que envié un conjunto de cambios a su servidor
disponible públicamente, esos cambios no deben reescribirse. Git
intentará hacer cumplir esta regla si intenta enviar cambios que no
resulten en un “fast-forward merge” (es decir, cambios que no comparten
el mismo historial). Es posible anular esta comprobación, y puede haber
ocasiones en las que sea necesario reescribir un árbol exportado. Mover
conjuntos de cambios entre árboles para evitar conflictos en linux-next
es un ejemplo. Pero tales acciones deberían ser raras. Esta es una de las
razones por las que el desarrollo debe hacerse en ramas privadas (que se
pueden reescribir si es necesario) y solo trasladarse a ramas públicas
cuando esté en un estado razonablemente avanzado.
A medida que el mainline (u otro árbol en el que se basa un conjunto de
cambios) avanza, es tentador fusionarse con ese árbol para permanecer a
la vanguardia. Para una rama privada, la rebase puede ser una manera fácil
de mantenerse al día con otro árbol, pero la rebase no es una opción una
vez que el árbol se exporta al mundo. Una vez que eso sucede, se debe
realizar una fusión completa. Fusionar ocasionalmente tiene sentido, pero
las fusiones demasiado frecuentes pueden desordenar el historial
innecesariamente. La técnica sugerida en este caso es fusionar con poca
frecuencia y, por lo general, solo en puntos de lanzamiento específicos
(como una versión -rc del mainline). Si está nervioso por cambios
específicos, siempre puede realizar fusiones de prueba en una rama
privada. La herramienta git “rerere” puede ser útil en tales situaciones;
recuerda cómo se resolvieron los conflictos de fusión para que no tenga
que hacer el mismo trabajo dos veces.
Una de las mayores quejas recurrentes sobre herramientas como git es la
siguiente: el movimiento masivo de parches de un repositorio a otro hace
que sea fácil deslizar cambios más aconsejados que pasan al mainline
debajo del radar de revisión. Los desarrolladores del kernel tienden a
descontentarse cuando ven que suceden ese tipo de cosas; poner un árbol
de git con parches no revisados o fuera de tema puede afectar su capacidad
para hacer que los árboles sean integrados en el futuro. Citando a Linus:
::
Puede enviarme parches, pero para que yo acepte un parche de git de
su parte, necesito saber que usted sabe lo que está haciendo, y
necesito poder confiar en las cosas *sin* tener que revisar
manualmente cada cambio individual.
(https://lwn.net/Articles/224135/).
Para evitar este tipo de situación, asegúrese de que todos los parches
dentro de una rama determinada se adhieran estrictamente al tema asociado;
una rama de “correcciones de drivers” no debería hacer cambios en el
código central de gestión de memoria. Y, lo más importante, no utilice un
árbol git para eludir el proceso de revisión. Publique un resumen
ocasional del árbol en la lista relevante y, cuando sea el momento
adecuado, solicite que el árbol se incluya en linux-next.
Si y cuando otros comiencen a enviar parches para su inclusión en su
árbol, no olvide revisarlos. Además, asegúrese de mantener la información
de autoría correcta; la herramienta git “am” hace lo mejor que puede es
este sentido, pero es posible que tenga que agregar una línea “From:” al
parche si ha sido reenviado a través de un tercero.
Al solicitar un pull, proporcione toda la información relevante: dónde
está su árbol, qué rama se debe pull, y que cambios resultarán del pull.
El comando git request-pull puede ser útil en este sentido; formateará la
solicitud como otros desarrolladores esperan, y también comprobará para
asegurarse de que ha recordado enviar esos cambios al servidor público.
Revisión de parches
-------------------
Algunos lectores seguramente se opondrán a incluir esta sección con
“temas avanzados” porque incluso los desarrolladores principiantes del
kernel deberían revisar los parches. Es cierto que no hay mejor manera de
aprender a programar en el entorno del kernel que mirando el código
publicado por otros. Además, los revisores siempre escasean; al revisar
código, puede contribuir significativamente al proceso en su conjunto.
Revisar el código puede ser una perspectiva intimidante, especialmente
para un nuevo desarrollador de kernel que puede sentirse nervioso al
cuestionar el código – en público – publicado por aquellos con más
experiencia. Sin embargo, incluso el código escrito por los desarrolladores
más experimentados se puede mejorar. Quizás el mejor consejo para los
revisores (todos los revisores) es este: expresar los comentarios de
revisión como preguntas en lugar de críticas. Preguntar “¿cómo se libera
el bloqueo en este camino?” siempre funcionará mejor que decir “el
bloqueo aquí es incorrecto”.
Otra técnica que es útil en caso de desacuerdo es pedir a otros que
intervengan. Si una discusión llega a un punto muerto después de algunos
intercambios, solicite las opiniones de otros revisores o maintainers. A
menudo, aquellos que están de acuerdo con un revisor permanecen en
silencio a menos que se les invite a participar. La opinión de varias
personas tiene exponencialmente más peso.
Diferentes desarrolladores revisarán el código desde diferentes puntos de
vista. Algunos se preocupan principalmente por el estilo de codificación
y si las líneas de código tienen espacios en blanco al final. Otros se
enfocarán principalmente en si el cambio implementado por el parche en su
totalidad es beneficioso para el kernel o no. Sin embargo, otros
comprobarán si hay bloqueos problemáticos, uso excesivo de la pila,
posibles problemas de seguridad, duplicación de código encontrado en
otras partes, documentación adecuada, efectos adversos en el rendimiento,
cambios en la ABI del espacio de usuario, etcétera. Todos los tipos de
revisión, si conducen a un mejor código en el kernel, son bienvenidos y
valen la pena.
No hay ningún requisito estricto para usar etiquetas específicas como
``Reviewed-by``. De hecho, las revisiones en Inglés sencillo son más
informativas y alentadas incluso cuando se proporciona una etiqueta, por
ejemplo, “Revisé los aspectos A, B y C de esta propuesta y me parece
bien”.
¡Alguna forma de mensaje de revisión o respuesta es obviamente necesaria,
de lo contrario, los maintainers no sabrán que el revisor ha revisado el
parche en absoluto!
Por último, pero no menos importante, la revisión de parches puede
convertirse en un proceso negativo, centrado en señalar problemas. ¡Por
favor, dé un cumplido de vez en cuando, especialmente a los principiantes!
@@ -0,0 +1,82 @@
.. include:: ../disclaimer-sp.rst
:Original: Documentation/process/8.Conclusion.rst
:Translator: Carlos Bilbao <carlos.bilbao.osdev@gmail.com> and Avadhut Naik <avadhut.naik@amd.com>
.. _sp_development_conclusion:
Para más información
====================
Hay numerosas fuentes de información sobre el desarrollo del kernel de
Linux y temas relacionados. La primera de ellas será el directorio de
Documentación (Documentation) que se encuentra en la distribución del
código fuente del kernel. Comience con el nivel superior
:ref:`Documentation/translations/sp_SP/process/howto.rst <sp_process_howto>`;
también lea
:ref:`Documentation/translations/sp_SP/process/submitting-patches.rst <sp_submittingpatches>`.
Muchas API internas del kernel están documentadas utilizando el mecanismo
de kerneldoc; “make htmldocs” o “make pdfdocs” se pueden usar para
generar esos documentos en formato HTML o PDF (aunque la versión de TeX
incluida en algunas distribuciones tiene límites internos y no procesa
los documentos correctamente).
Varios sitios web discuten el desarrollo del kernel en todos los niveles
de detalle. A su autor le gustaría sugerir humildemente https://lwn.net/
como fuente. La información sobre muchos temas específicos del kernel se
puede encontrar a través del índice del kernel de LWN en:
https://lwn.net/Kernel/Index/
Más allá de eso, un recurso valioso para los desarrolladores del kernel
es:
https://kernelnewbies.org/
Y, por supuesto, no se debe olvidar https://kernel.org/, la ubicación
definitiva para información de lanzamiento del kernel.
Hay varios libros sobre el desarrollo del kernel:
Linux Device Drivers, 3rd Edition (Jonathan Corbet, Alessandro
Rubini, and Greg Kroah-Hartman). En linea en
https://lwn.net/Kernel/LDD3/.
Linux Kernel Development (Robert Love).
Understanding the Linux Kernel (Daniel Bovet and Marco Cesati).
Todos estos libros padecen un defecto común: suelen estar algo obsoletos
cuando llegan a las estanterías, y ya llevan un tiempo en las estanterías.
Aun así, hay bastante buena información que se puede encontrar allí.
La documentación de git se puede encontrar en:
https://www.kernel.org/pub/software/scm/git/docs/
https://www.kernel.org/pub/software/scm/git/docs/user-manual.html
Conclusión
==========
Felicitaciones a todos los que han logrado leer este extenso documento.
Con suerte, ha proporcionado una comprensión útil de cómo se desarrolla
el kernel Linux y cómo puede participar en ese proceso.
Al final, lo que importa es la participación. Cualquier proyecto de
software de código abierto no es más que la suma de lo que sus
colaboradores aportan. El kernel Linux ha progresado tan rápido y tan como
lo ha hecho porque ha sido ayudado por un grupo impresionantemente grande
de desarrolladores, todos los cuales están trabajando para mejorarlo. El
kernel es un excelente ejemplo de lo que se puede lograr cuando miles de
personas trabajan juntas hacia un objetivo común.
Sin embargo, el kernel siempre puede beneficiarse de una base de
desarrolladores más grande. Siempre hay más trabajo por hacer. Pero, lo
que es igual de importante, la mayoría de los demás participantes en el
ecosistema Linux pueden beneficiarse contribuyendo al kernel. Introducir
código en el mainline es la clave para una mayor calidad del código,
menores costes de mantenimiento y distribución, un mayor nivel de
influencia sobre la dirección del desarrollo del kernel y más. Es una
situación en la que todos los involucrados ganan. Encienda su editor y
únase a nosotros; será más que bienvenido.
@@ -0,0 +1,632 @@
.. include:: ../disclaimer-sp.rst
:Original: :ref:`Documentation/process/adding-syscalls.rst <addsyscalls>`
:Translator: Mauricio Fuentes <mauriciofb@gmail.com>
.. _sp_addsyscalls:
Agregando una Nueva Llamada del Sistema
=======================================
Este documento describe qué involucra agregar una nueva llamada del sistema
al kernel Linux, más allá de la presentación y consejos normales en
:ref:`Documentation/process/submitting-patches.rst <submittingpatches>` que
también puede encontrar traducido a este idioma.
Alternativas a Llamadas del Sistema
-----------------------------------
La primera cosa a considerar cuando se agrega una llamada al sistema es si
alguna alternativa es adecuada en su lugar. Aunque las llamadas al sistema
son los puntos de interacción entre el userspace y el kernel más obvios y
tradicionales, existen otras posibilidades -- elija la que mejor se adecúe
a su interfaz.
- Si se puede hacer que la operación se parezca a un objeto filesystem,
podría tener más sentido crear un nuevo sistema de ficheros o
dispositivo. Esto también hará más fácil encapsular la nueva
funcionalidad en un módulo del kernel en vez de requerir que sea
construido junto al kernel principal.
- Si la nueva funcionalidad involucra operaciones donde el kernel
notifica al userspace que algo ha pasado, entonces retornar un nuevo
descriptor de archivo para el objeto relevante permite al userspace
usar ``poll``/``select``/``epoll`` para recibir esta notificación.
- Sin embargo, operaciones que no mapean a operaciones similares a
:manpage:`read(2)`/:manpage:`write(2)` tienen que ser implementadas
como solicitudes :manpage:`ioctl(2)`, las cuales pueden llevar a un
API algo opaca.
- Si sólo está exponiendo información del runtime, un nuevo nodo en sysfs
(mire ``Documentation/filesystems/sysfs.rst``) o el filesystem ``/proc``
podría ser más adecuado. Sin embargo, acceder a estos mecanismos
requiere que el filesystem relevante esté montado, lo que podría no ser
siempre el caso (e.g. en un ambiente namespaced/sandboxed/chrooted).
Evite agregar cualquier API a debugfs, ya que no se considera una
interfaz (interface) de 'producción' para el userspace.
- Si la operación es específica a un archivo o descriptor de archivo
específico, entonces la opción de comando adicional :manpage:`fcntl(2)`
podría ser más apropiada. Sin embargo, :manpage:`fcntl(2)` es una
llamada al sistema multiplexada que esconde mucha complejidad, así que
esta opción es mejor cuando la nueva funcion es analogamente cercana a
la funcionalidad existente :manpage:`fcntl(2)`, o la nueva funcionalidad
es muy simple (por ejemplo, definir/obtener un flag simple relacionado a
un descriptor de archivo).
- Si la operación es específica a un proceso o tarea particular, entonces
un comando adicional :manpage:`prctl(2)` podría ser más apropiado. Tal
como con :manpage:`fcntl(2)`, esta llamada al sistema es un multiplexor
complicado así que está reservado para comandos análogamente cercanos
del existente ``prctl()`` u obtener/definir un flag simple relacionado a
un proceso.
Diseñando el API: Planeando para extensiones
--------------------------------------------
Una nueva llamada del sistema forma parte del API del kernel, y tiene que
ser soportada indefinidamente. Como tal, es una muy buena idea discutir
explícitamente el interface en las listas de correo del kernel, y es
importante planear para futuras extensiones del interface.
(La tabla syscall está poblada con ejemplos históricos donde esto no se
hizo, junto con los correspondientes seguimientos de los system calls --
``eventfd``/``eventfd2``, ``dup2``/``dup3``, ``inotify_init``/``inotify_init1``,
``pipe``/``pipe2``, ``renameat``/``renameat2`` -- así que aprenda de la
historia del kernel y planee extensiones desde el inicio.)
Para llamadas al sistema más simples que sólo toman un par de argumentos,
la forma preferida de permitir futuras extensiones es incluir un argumento
flag a la llamada al sistema. Para asegurarse que el userspace pueda usar
de forma segura estos flags entre versiones del kernel, revise si los flags
contienen cualquier flag desconocido, y rechace la llamada al sistema (con
``EINVAL``) si ocurre::
if (flags & ~(THING_FLAG1 | THINGFLAG2 | THING_FLAG3))
return -EINVAL;
(Si no hay valores de flags usados aún, revise que los argumentos del flag
sean cero.)
Para llamadas al sistema más sofisticadas que involucran un gran número de
argumentos, es preferible encapsular la mayoría de los argumentos en una
estructura que sea pasada a través de un puntero. Tal estructura puede
hacer frente a futuras extensiones mediante la inclusión de un argumento de
tamaño en la estructura::
struct xyzzy_params {
u32 size; /* userspace define p->size = sizeof(struct xyzzy_params) */
u32 param_1;
u64 param_2;
u64 param_3;
};
Siempre que cualquier campo añadido subsecuente, digamos ``param_4``, sea
diseñado de forma tal que un valor cero, devuelva el comportamiento previo,
entonces permite versiones no coincidentes en ambos sentidos:
- Para hacer frente a programas del userspace más modernos, haciendo
llamadas a un kernel más antiguo, el código del kernel debe revisar que
cualquier memoria más allá del tamaño de la estructura sea cero (revisar
de manera efectiva que ``param_4 == 0``).
- Para hacer frente a programas antiguos del userspace haciendo llamadas a
un kernel más nuevo, el código del kernel puede extender con ceros, una
instancia más pequeña de la estructura (definiendo efectivamente
``param_4 == 0``).
Revise :manpage:`perf_event_open(2)` y la función ``perf_copy_attr()`` (en
``kernel/events/code.c``) para un ejemplo de esta aproximación.
Diseñando el API: Otras consideraciones
---------------------------------------
Si su nueva llamada al sistema permite al userspace hacer referencia a un
objeto del kernel, esta debería usar un descriptor de archivo como el
manipulador de ese objeto -- no invente un nuevo tipo de objeto manipulador
userspace cuando el kernel ya tiene mecanismos y semánticas bien definidas
para usar los descriptores de archivos.
Si su nueva llamada a sistema xyzzy(2) retorna un nuevo
descriptor de archivo, entonces el argumento flag debe incluir un valor que
sea equivalente a definir ``O_CLOEXEC`` en el nuevo FD. Esto hace posible
al userspace acortar la brecha de tiempo entre ``xyzzy()`` y la llamada a
``fcntl(fd, F_SETFD, FD_CLOEXEC)``, donde un ``fork()`` inesperado y
``execve()`` en otro hilo podrían filtrar un descriptor al programa
ejecutado. (Sin embargo, resista la tentación de reusar el valor actual de
la constante ``O_CLOEXEC``, ya que es específica de la arquitectura y es
parte de un espacio numerado de flags ``O_*`` que está bastante lleno.)
Si su llamada de sistema retorna un nuevo descriptor de archivo, debería
considerar también que significa usar la familia de llamadas de sistema
:manpage:`poll(2)` en ese descriptor de archivo. Hacer un descriptor de
archivo listo para leer o escribir es la forma normal para que el kernel
indique al espacio de usuario que un evento ha ocurrido en el
correspondiente objeto del kernel.
Si su nueva llamada de sistema xyzzy(2) involucra algún nombre
de archivo como argumento::
int sys_xyzzy(const char __user *path, ..., unsigned int flags);
debería considerar también si una versión xyzzyat(2) es mas
apropiada::
int sys_xyzzyat(int dfd, const char __user *path, ..., unsigned int flags);
Esto permite más flexibilidad en como el userspace especifica el archivo en
cuestión; en particular esto permite al userspace pedir la funcionalidad a
un descriptor de archivo ya abierto usando el flag ``AT_EMPTY_PATH``,
efectivamente dando una operación fxyzzy(3) gratis::
- xyzzyat(AT_FDCWD, path, ..., 0) es equivalente a xyzzy(path, ...)
- xyzzyat(fd, "", ..., AT_EMPTY_PATH) es equivalente a fxyzzy(fd, ...)
(Para más detalles sobre la explicación racional de las llamadas \*at(),
revise el man page :manpage:`openat(2)`; para un ejemplo de AT_EMPTY_PATH,
mire el man page :manpage:`fstatat(2)` manpage.)
Si su nueva llamada de sistema xyzzy(2) involucra un parámetro
describiendo un describiendo un movimiento dentro de un archivo, ponga de
tipo ``loff_t`` para que movimientos de 64-bit puedan ser soportados
incluso en arquitecturas de 32-bit.
Si su nueva llamada de sistema xyzzy(2) involucra una
funcionalidad privilegiada, esta necesita ser gobernada por la capability
bit linux apropiada (revisado con una llamada a ``capable()``), como se
describe en el man page :manpage:`capabilities(7)`. Elija una parte de
capability linux que govierne las funcionalidades relacionadas, pero trate
de evitar combinar muchas funciones sólo relacionadas vagamente bajo la
misma sección, ya que va en contra de los propósitos de las capabilities de
dividir el poder del usuario root. En particular, evite agregar nuevos usos
de la capacidad ya demasiado general de la capabilities ``CAP_SYS_ADMIN``.
Si su nueva llamada de sistema xyzzy(2) manipula un proceso que
no es el proceso invocado, este debería ser restringido (usando una llamada
a ``ptrace_may_access()``) de forma que el único proceso con los mismos
permisos del proceso objetivo, o con las capacidades (capabilities)
necesarias, pueda manipulador el proceso objetivo.
Finalmente, debe ser conciente de que algunas arquitecturas no-x86 tienen
un manejo más sencillo si los parámetros que son explícitamente 64-bit
caigan en argumentos enumerados impares (i.e. parámetros 1,3,5), para
permitir el uso de pares contiguos de registros 32-bits. (Este cuidado no
aplica si el argumento es parte de una estructura que se pasa a través de
un puntero.)
Proponiendo el API
------------------
Para hacer una nueva llamada al sistema fácil de revisar, es mejor dividir
el patchset (conjunto de parches) en trozos separados. Estos deberían
incluir al menos los siguientes items como commits distintos (cada uno de
los cuales se describirá más abajo):
- La implementación central de la llamada al sistema, junto con
prototipos, numeración genérica, cambios Kconfig e implementaciones de
rutinas de respaldo (fallback stub)
- Conectar la nueva llamada a sistema a una arquitectura particular,
usualmente x86 (incluyendo todas las x86_64, x86_32 y x32).
- Una demostración del use de la nueva llamada a sistema en el userspace
vía un selftest en ``tools/testing/selftest/``.
- Un borrador de man-page para la nueva llamada a sistema, ya sea como
texto plano en la carta de presentación, o como un parche (separado)
para el repositorio man-pages.
Nuevas propuestas de llamadas de sistema, como cualquier cambio al API del
kernel, debería siempre ser copiado a linux-api@vger.kernel.org.
Implementation de Llamada de Sistema Generica
---------------------------------------------
La entrada principal a su nueva llamada de sistema xyzzy(2) será
llamada ``sys_xyzzy()``, pero incluya este punto de entrada con la macro
``SYSCALL_DEFINEn()`` apropiada en vez de explicitamente. El 'n' indica el
numero de argumentos de la llamada de sistema, y la macro toma el nombre de
la llamada de sistema seguida por el par (tipo, nombre) para los parámetros
como argumentos. Usar esta macro permite a la metadata de la nueva llamada
de sistema estar disponible para otras herramientas.
El nuevo punto de entrada también necesita un prototipo de función
correspondiente en ``include/linux/syscalls.h``, marcado como asmlinkage
para calzar en la manera en que las llamadas de sistema son invocadas::
asmlinkage long sys_xyzzy(...);
Algunas arquitecturas (e.g. x86) tienen sus propias tablas de syscall
específicas para la arquitectura, pero muchas otras arquitecturas comparten
una tabla de syscall genéricas. Agrega su nueva llamada de sistema a la
lista genérica agregando una entrada a la lista en
``include/uapi/asm-generic/unistd.h``::
#define __NR_xyzzy 292
__SYSCALL(__NR_xyzzy, sys_xyzzy )
También actualice el conteo de __NR_syscalls para reflejar la llamada de
sistema adicional, y note que si multiples llamadas de sistema nuevas son
añadidas en la misma ventana unida, su nueva llamada de sistema podría
tener que ser ajustada para resolver conflictos.
El archivo ``kernel/sys_ni.c`` provee una implementación fallback stub
(rutina de respaldo) para cada llamada de sistema, retornando ``-ENOSYS``.
Incluya su nueva llamada a sistema aquí también::
COND_SYSCALL(xyzzy);
Su nueva funcionalidad del kernel, y la llamada de sistema que la controla,
debería normalmente ser opcional, así que incluya una opción ``CONFIG``
(tipicamente en ``init/Kconfig``) para ella. Como es usual para opciones
``CONFIG`` nuevas:
- Incluya una descripción para la nueva funcionalidad y llamada al sistema
controlada por la opción.
- Haga la opción dependiendo de EXPERT si esta debe estar escondida de los
usuarios normales.
- Haga que cualquier nuevo archivo fuente que implemente la función
dependa de la opción CONFIG en el Makefile (e.g.
``obj-$(CONFIG_XYZZY_SYSCALL) += xyzzy.o``).
- Revise dos veces que el kernel se siga compilando con la nueva opción
CONFIG apagada.
Para resumir, necesita un commit que incluya:
- una opción ``CONFIG`` para la nueva función, normalmente en ``init/Kconfig``
- ``SYSCALL_DEFINEn(xyzzy, ...)`` para el punto de entrada
- El correspondiente prototipo en ``include/linux/syscalls.h``
- Una entrada genérica en ``include/uapi/asm-generic/unistd.h``
- fallback stub en ``kernel/sys_ni.c``
Implementación de Llamada de Sistema x86
----------------------------------------
Para conectar su nueva llamada de sistema a plataformas x86, necesita
actualizar las tablas maestras syscall. Asumiendo que su nueva llamada de
sistema ni es especial de alguna manera (revise abajo), esto involucra una
entrada "común" (para x86_64 y x86_32) en
arch/x86/entry/syscalls/syscall_64.tbl::
333 common xyzz sys_xyzzy
y una entrada "i386" en ``arch/x86/entry/syscalls/syscall_32.tbl``::
380 i386 xyzz sys_xyzzy
De nuevo, estos número son propensos de ser cambiados si hay conflictos en
la ventana de integración relevante.
Compatibilidad de Llamadas de Sistema (Genérica)
------------------------------------------------
Para la mayoría de llamadas al sistema la misma implementación 64-bit puede
ser invocada incluso cuando el programa de userspace es en si mismo 32-bit;
incluso si los parámetros de la llamada de sistema incluyen un puntero
explícito, esto es manipulado de forma transparente.
Sin embargo, existe un par de situaciones donde se necesita una capa de
compatibilidad para lidiar con las diferencias de tamaño entre 32-bit y
64-bit.
La primera es si el kernel 64-bit también soporta programas del userspace
32-bit, y por lo tanto necesita analizar areas de memoria del (``__user``)
que podrían tener valores tanto 32-bit como 64-bit. En particular esto se
necesita siempre que un argumento de la llamada a sistema es:
- un puntero a un puntero
- un puntero a un struc conteniendo un puntero (por ejemplo
``struct iovec __user *``)
- un puntero a un type entero de tamaño entero variable (``time_t``,
``off_t``, ``long``, ...)
- un puntero a un struct conteniendo un type entero de tamaño variable.
La segunda situación que requiere una capa de compatibilidad es cuando uno
de los argumentos de la llamada a sistema tiene un argumento que es
explícitamente 64-bit incluso sobre arquitectura 32-bit, por ejemplo
``loff_t`` o ``__u64``. En este caso, el valor que llega a un kernel 64-bit
desde una aplicación de 32-bit se separará en dos valores de 32-bit, los
que luego necesitan ser reensamblados en la capa de compatibilidad.
(Note que un argumento de una llamada a sistema que sea un puntero a un
type explicitamente de 64-bit **no** necesita una capa de compatibilidad;
por ejemplo, los argumentos de :manpage:`splice(2)`) del tipo
``loff_t __user *`` no significan la necesidad de una llamada a sistema
``compat_``.)
La versión compatible de la llamada de sistema se llama
``compat_sys_xyzzy()``, y se agrega con la macro
``COMPAT_SYSCALL_DEFINEn``, de manera análoga a SYSCALL_DEFINEn. Esta
versión de la implementación se ejecuta como parte de un kernel de 64-bit,
pero espera recibir parametros con valores 32-bit y hace lo que tenga que
hacer para tratar con ellos. (Típicamente, la versión ``compat_sys_``
convierte los valores a versiones de 64 bits y llama a la versión ``sys_``
o ambas llaman a una función de implementación interna común.)
El punto de entrada compat también necesita un prototipo de función
correspondiente, en ``include/linux/compat.h``, marcado como asmlinkage
para igualar la forma en que las llamadas al sistema son invocadas::
asmlinkage long compat_sys_xyzzy(...);
Si la nueva llamada al sistema involucra una estructura que que se dispone
de forma distinta en sistema de 32-bit y 64-bit, digamos
``struct xyzzy_args``, entonces el archivo de cabecera
include/linux/compat.h también debería incluir una versión compatible de la
estructura (``struct compat_xyzzy_args``) donde cada campo de tamaño
variable tiene el tipo ``compat_`` apropiado que corresponde al tipo en
``struct xyzzy_args``. La rutina ``compat_sys_xyzzy()`` puede entonces usar
esta estructura ``compat_`` para analizar los argumentos de una invocación
de 32-bit.
Por ejemplo, si hay campos::
struct xyzzy_args {
const char __user *ptr;
__kernel_long_t varying_val;
u64 fixed_val;
/* ... */
};
en struct xyzzy_args, entonces struct compat_xyzzy_args debe tener::
struct compat_xyzzy_args {
compat_uptr_t ptr;
compat_long_t varying_val;
u64 fixed_val;
/* ... */
};
la lista genérica de llamadas al sistema también necesita ajustes para
permitir la versión compat; la entrada en
``include/uapi/asm-generic/unistd.h`` debería usar ``__SC_COMP`` en vez de
``__SYSCALL``::
#define __NR_xyzzy 292
__SC_COMP(__NR_xyzzy, sys_xyzzy, compat_sys_xyzzy)
Para resumir, necesita:
- una ``COMPAT_SYSCALL_DEFINEn(xyzzy, ...)`` para el punto de entrada de compat.
- el prototipo correspondiente en ``include/linux/compat.h``
- (en caso de ser necesario) un struct de mapeo de 32-bit en ``include/linux/compat.h``
- una instancia de ``__SC_COMP`` no ``__SYSCALL`` en ``include/uapi/asm-generic/unistd.h``
Compatibilidad de Llamadas de Sistema (x86)
-------------------------------------------
Para conectar la arquitectura x86 de una llamada al sistema con una versión
de compatibilidad, las entradas en las tablas de syscall deben ser
ajustadas.
Primero, la entrada en ``arch/x86/entry/syscalls/syscall_32.tbl`` recibe
una columna extra para indicar que un programa del userspace de 32-bit
corriendo en un kernel de 64-bit debe llegar al punto de entrada compat::
380 i386 xyzzy sys_xyzzy __ia32_compat_sys_xyzzy
Segundo, tienes que averiguar qué debería pasar para la versión x32 ABI de
la nueva llamada al sistema. Aquí hay una elección: el diseño de los
argumentos debería coincidir con la versión de 64-bit o la versión de
32-bit.
Si hay involucrado un puntero-a-puntero, la decisión es fácil: x32 es
ILP32, por lo que el diseño debe coincidir con la versión 32-bit, y la
entrada en ``arch/x86/entry/syscalls/syscall_64.tbl`` se divide para que
progamas 32-bit lleguen al envoltorio de compatibilidad::
333 64 xyzzy sys_xyzzy
...
555 x32 xyzzy __x32_compat_sys_xyzzy
Si no hay punteros involucrados, entonces es preferible reutilizar el system
call 64-bit para el x32 ABI (y consecuentemente la entrada en
arch/x86/entry/syscalls/syscall_64.tbl no se cambia).
En cualquier caso, debes revisar que lo tipos involucrados en su diseño de
argumentos de hecho asigne exactamente de x32 (-mx32) a 32-bit(-m32) o
equivalentes 64-bit (-m64).
Llamadas de Sistema Retornando a Otros Lugares
----------------------------------------------
Para la mayoría de las llamadas al sistema, una vez que se la llamada al
sistema se ha completado el programa de usuario continúa exactamente donde
quedó -- en la siguiente instrucción, con el stack igual y la mayoría de
los registros igual que antes de la llamada al sistema, y con el mismo
espacio en la memoria virtual.
Sin embargo, unas pocas llamadas al sistema hacen las cosas diferente.
Estas podrían retornar a una ubicación distinta (``rt_sigreturn``) o
cambiar el espacio de memoria (``fork``/``vfork``/``clone``) o incluso de
arquitectura (``execve``/``execveat``) del programa.
Para permitir esto, la implementación del kernel de la llamada al sistema
podría necesitar guardar y restaurar registros adicionales al stak del
kernel, brindandole control completo de donde y cómo la ejecución continúa
después de la llamada a sistema.
Esto es arch-specific, pero típicamente involucra definir puntos de entrada
assembly que guardan/restauran registros adicionales e invocan el punto de
entrada real de la llamada a sistema.
Para x86_64, esto es implementado como un punto de entrada ``stub_xyzzy``
en ``arch/x86/entry/entry_64.S``, y la entrada en la tabla syscall
(``arch/x86/entry/syscalls/syscall_32.tbl``) es ajustada para calzar::
333 common xyzzy stub_xyzzy
El equivalente para programas 32-bit corriendo en un kernel 64-bit es
normalmente llamado ``stub32_xyzzy`` e implementado en
``arch/x86/entry/entry_64_compat.S``, con el correspondiente ajuste en la
tabla syscall en ``arch/x86/syscalls/syscall_32.tbl``::
380 i386 xyzzy sys_xyzzy stub32_xyzzy
Si la llamada a sistema necesita una capa de compatibilidad (como en la
sección anterior) entonces la versión ``stub32_`` necesita llamar a la
versión ``compat_sys_`` de la llamada a sistema, en vez de la versión
nativa de 64-bit. También, si la implementación de la versión x32 ABI no es
comun con la versión x86_64, entonces su tabla syscall también necesitará
invocar un stub que llame a la versión ``compat_sys_``
Para completar, también es agradable configurar un mapeo de modo que el
user-mode linux todavía funcione -- su tabla syscall referenciará
stub_xyzzy, pero el UML construido no incluye una implementación
``arch/x86/entry/entry_64.S``. Arreglar esto es tan simple como agregar un
#define a ``arch/x86/um/sys_call_table_64.c``::
#define stub_xyzzy sys_xyzzy
Otros detalles
--------------
La mayoría del kernel trata las llamadas a sistema de manera genérica, pero
está la excepción ocasional que pueda requerir actualización para su
llamada a sistema particular.
El subsistema de auditoría es un caso especial; este incluye funciones
(arch-specific) que clasifican algunos tipos especiales de llamadas al
sistema -- específicamente file open (``open``/``openat``), program
execution (``execve`` /``execveat``) o operaciones multiplexores de socket
(``socketcall``). Si su nueva llamada de sistema es análoga a alguna de
estas, entonces el sistema auditor debe ser actualizado.
Más generalmente, si existe una llamada al sistema que sea análoga a su
nueva llamada al sistema, entonces vale la pena hacer un grep a todo el
kernel de la llamada a sistema existente, para revisar que no exista otro
caso especial.
Testing
-------
Una nueva llamada al sistema debe obviamente ser probada; también es útil
proveer a los revisores con una demostración de cómo los programas del
userspace usarán la llamada al sistema. Una buena forma de combinar estos
objetivos es incluir un simple programa self-test en un nuevo directorio
bajo ``tools/testing/selftests/``.
Para una nueva llamada al sistema, obviamente no habrá una función
envoltorio libc por lo que el test necesitará ser invocado usando
``syscall()``; también, si la llamada al sistema involucra una nueva
estructura userspace-visible, el encabezado correspondiente necesitará ser
instalado para compilar el test.
Asegure que selftest corra satisfactoriamente en todas las arquitecturas
soportadas. Por ejemplo, revise si funciona cuando es compilado como un
x86_64 (-m64), x86_32 (-m32) y x32 (-mx32) programa ABI.
Para pruebas más amplias y exhautivas de la nueva funcionalidad, también
debería considerar agregar tests al Linus Test Project, o al proyecto
xfstests para cambios filesystem-related
- https://linux-test-project.github.io/
- git://git.kernel.org/pub/scm/fs/xfs/xfstests-dev.git
Man Page
--------
Todas las llamada al sistema nueva deben venir con un man page completo,
idealmente usando groff markup, pero texto plano también funciona. Si se
usa groff, es útil incluir una versión ASCII pre-renderizada del man-page
en el cover del email para el patchset, para la conveniencia de los
revisores.
El man page debe ser cc'do a linux-man@vger.kernel.org
Para más detalles, revise https://www.kernel.org/doc/man-pages/patches.html
No invoque las llamadas de sistemas en el kernel
------------------------------------------------
Las llamadas al sistema son, cómo se declaró más arriba, puntos de
interacción entre el userspace y el kernel. Por lo tanto, las funciones de
llamada al sistema como ``sys_xyzzy()`` o ``compat_sys_xyzzy()`` deberían
ser llamadas sólo desde el userspace vía la tabla de syscall, pero no de
otro lugar en el kernel. Si la funcionalidad syscall es útil para ser usada
dentro del kernel, necesita ser compartida entre syscalls nuevas o
antiguas, o necesita ser compartida entre una syscall y su variante de
compatibilidad, esta debería ser implementada mediante una función "helper"
(como ``ksys_xyzzy()``). Esta función del kernel puede ahora ser llamada
dentro del syscall stub (``sys_xyzzy()``), la syscall stub de
compatibilidad (``compat_sys_xyzzy()``), y/o otro código del kernel.
Al menos en 64-bit x86, será un requerimiento duro desde la v4.17 en
adelante no invocar funciones de llamada al sistema (system call) en el
kernel. Este usa una convención de llamada diferente para llamadas al
sistema donde ``struct pt_regs`` es decodificado on-the-fly en un
envoltorio syscall que luego entrega el procesamiento al syscall real. Esto
significa que sólo aquellos parámetros que son realmente necesarios para
una syscall específica son pasados durante la entrada del syscall, en vez
de llenar en seis registros de CPU con contenido random del userspace todo
el tiempo (los cuales podrían causar serios problemas bajando la cadena de
llamadas).
Más aún, reglas sobre cómo se debería acceder a la data pueden diferir
entre la data del kernel y la data de usuario. Esta es otra razón por la
cual llamar a ``sys_xyzzy()`` es generalmente una mala idea.
Excepciones a esta regla están permitidas solamente en overrides
específicos de arquitectura, envoltorios de compatibilidad específicos de
arquitectura, u otro código en arch/.
Referencias y fuentes
---------------------
- Artículo LWN de Michael Kerrisk sobre el uso de argumentos flags en llamadas al
sistema:
https://lwn.net/Articles/585415/
- Artículo LWN de Michael Kerrisk sobre cómo manejar flags desconocidos en una
llamada al sistema: https://lwn.net/Articles/588444/
- Artículo LWN de Jake Edge describiendo restricciones en argumentos en
64-bit system call: https://lwn.net/Articles/311630/
- Par de artículos LWN de David Drysdale que describen la ruta de implementación
de llamadas al sistema en detalle para v3.14:
- https://lwn.net/Articles/604287/
- https://lwn.net/Articles/604515/
- Requerimientos arquitectura-específicos para llamadas al sistema son discutidos en el
:manpage:`syscall(2)` man-page:
http://man7.org/linux/man-pages/man2/syscall.2.html#NOTES
- Recopilación de emails de Linus Torvalds discutiendo problemas con ``ioctl()``:
https://yarchive.net/comp/linux/ioctl.html
- "How to not invent kernel interfaces", Arnd Bergmann,
https://www.ukuug.org/events/linux2007/2007/papers/Bergmann.pdf
- Artículo LWN de Michael Kerrisk sobre evitar nuevos usos de CAP_SYS_ADMIN:
https://lwn.net/Articles/486306/
- Recomendaciones de Andrew Morton que toda la información relacionada a una nueva
llamada al sistema debe venir en el mismo hilo de correos:
https://lore.kernel.org/r/20140724144747.3041b208832bbdf9fbce5d96@linux-foundation.org
- Recomendaciones de Michael Kerrisk que una nueva llamada al sistema debe venir
con un man-page: https://lore.kernel.org/r/CAKgNAkgMA39AfoSoA5Pe1r9N+ZzfYQNvNPvcRN7tOvRb8+v06Q@mail.gmail.com
- Sugerencias de Thomas Gleixner que conexiones x86 deben ir en commits
separados: https://lore.kernel.org/r/alpine.DEB.2.11.1411191249560.3909@nanos
- Sugerencias de Greg Kroah-Hartman que es bueno para las nueva llamadas al sistema
que vengan con man-page y selftest: https://lore.kernel.org/r/20140320025530.GA25469@kroah.com
- Discusión de Michael Kerrisk de nuevas system call vs. extensiones :manpage:`prctl(2)`:
https://lore.kernel.org/r/CAHO5Pa3F2MjfTtfNxa8LbnkeeU8=YJ+9tDqxZpw7Gz59E-4AUg@mail.gmail.com
- Sugerencias de Ingo Molnar que llamadas al sistema que involucran múltiples
argumentos deben encapsular estos argumentos en una estructura, la cual incluye
un campo de tamaño para futura extensibilidad: https://lore.kernel.org/r/20150730083831.GA22182@gmail.com
- Enumerando rarezas por la (re-)utilización de O_* numbering space flags:
- commit 75069f2b5bfb ("vfs: renumber FMODE_NONOTIFY and add to uniqueness
check")
- commit 12ed2e36c98a ("fanotify: FMODE_NONOTIFY and __O_SYNC in sparc
conflict")
- commit bb458c644a59 ("Safer ABI for O_TMPFILE")
- Discusión de Matthew Wilcox sobre las restricciones en argumentos 64-bit:
https://lore.kernel.org/r/20081212152929.GM26095@parisc-linux.org
- Recomendaciones de Greg Kroah-Hartman sobre flags desconocidos deben ser
vigilados: https://lore.kernel.org/r/20140717193330.GB4703@kroah.com
- Recomendaciones de Linus Torvalds que las llamadas al sistema x32 deben favorecer
compatibilidad con versiones 64-bit sobre versiones 32-bit:
https://lore.kernel.org/r/CA+55aFxfmwfB7jbbrXxa=K7VBYPfAvmu3XOkGrLbB1UFjX1+Ew@mail.gmail.com
@@ -0,0 +1,97 @@
.. include:: ../disclaimer-sp.rst
:Original: :ref:`Documentation/process/code-of-conduct.rst <code_of_conduct>`
:Translator: Contributor Covenant and Carlos Bilbao <carlos.bilbao.osdev@gmail.com>
.. _sp_code_of_conduct:
Código de Conducta para Contribuyentes
+++++++++++++++++++++++++++++++++++++++
Nuestro Compromiso
==================
Nosotros, como miembros, contribuyentes y administradores nos comprometemos
a hacer de la participación en nuestra comunidad una experiencia libre de
acoso para todo el mundo, independientemente de la edad, dimensión corporal,
minusvalía visible o invisible, etnicidad, características sexuales,
identidad y expresión de género, nivel de experiencia, educación, nivel
socio-económico, nacionalidad, apariencia personal, raza, religión, o
identidad u orientación sexual. Nos comprometemos a actuar e interactuar de
maneras que contribuyan a una comunidad abierta, acogedora, diversa,
inclusiva y sana.
Nuestros Estándares
===================
Ejemplos de comportamiento que contribuyen a crear un ambiente positivo
para nuestra comunidad:
* Demostrar empatía y amabilidad ante otras personas
* Respeto a diferentes opiniones, puntos de vista y experiencias
* Dar y aceptar adecuadamente retroalimentación constructiva
* Aceptar la responsabilidad y disculparse ante quienes se vean afectados
por nuestros errores, aprendiendo de la experiencia
* Centrarse en lo que sea mejor no sólo para nosotros como individuos, sino
para la comunidad en general
Ejemplos de comportamiento inaceptable:
* El uso de lenguaje o imágenes sexualizadas, y aproximaciones o
atenciones sexuales de cualquier tipo
* Comentarios despectivos (trolling), insultantes o derogatorios, y ataques
personales o políticos
* El acoso en público o privado
* Publicar información privada de otras personas, tales como direcciones
físicas o de correo
electrónico, sin su permiso explícito
* Otras conductas que puedan ser razonablemente consideradas como
inapropiadas en un entorno profesional
Aplicación de las responsabilidades
===================================
Los administradores de la comunidad son responsables de aclarar y hacer
cumplir nuestros estándares de comportamiento aceptable y tomarán acciones
apropiadas y correctivas de forma justa en respuesta a cualquier
comportamiento que consideren inapropiado, amenazante, ofensivo o dañino.
Los administradores de la comunidad tendrán el derecho y la responsabilidad
de eliminar, editar o rechazar comentarios, commits, código, ediciones de
páginas de wiki, issues y otras contribuciones que no se alineen con este
Código de Conducta, y comunicarán las razones para sus decisiones de
moderación cuando sea apropiado.
Alcance
=======
Este código de conducta aplica tanto a espacios del proyecto como a
espacios públicos donde un individuo esté en representación del proyecto o
comunidad. Ejemplos de esto incluyen el uso de la cuenta oficial de correo
electrónico, publicaciones a través de las redes sociales oficiales, o
presentaciones con personas designadas en eventos en línea o no.
Aplicación
==========
Instancias de comportamiento abusivo, acosador o inaceptable de otro modo
podrán ser reportadas contactando el Code of Conduct Commitee a través de
<conduct@kernel.org>. Todas las quejas serán evaluadas e investigadas de
una manera puntual y justa. El Code of Condut Commitee está obligados a
respetar la privacidad y la seguridad de quienes reporten incidentes.
Detalles de políticas y aplicación en particular, serán incluidos por
separado.
Atribución
==========
Este Código de Conducta es una adaptación del Contributor Covenant, versión
1.4, disponible en https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
Interpretación
==============
Consulte el documento :ref:`code_of_conduct_interpretation` para ver cómo
interpretará la comunidad del kernel Linux este documento.
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,120 @@
.. SPDX-License-Identifier: GPL-2.0
.. include:: ../disclaimer-sp.rst
:Original: Documentation/process/contribution-maturity-model.rst
:Translator: Avadhut Naik <avadhut.naik@amd.com>
====================================================
Modelo de Madurez de Contribución al Kernel de Linux
====================================================
Los Antecedentes
================
Como parte de la cumbre de mantenedores del kernel de Linux 2021, hubo
una `discusión <https://lwn.net/Articles/870581/>`_ sobre los desafíos
en el reclutamiento de mantenedores del kernel, así como la sucesión de
los mantenedores. Algunas de las conclusiones de esa discusión incluyeron
que las empresas que forman parte de la comunidad del kernel de Linux
necesitan permitir que los ingenieros sean mantenedores como parte de su
trabajo, para que puedan convertirse en lideres respetados y finalmente,
en mantenedores del kernel. Para apoyar una fuente solida de talento, se
debe permitir y alentar a los desarrolladores a asumir contribuciones
upstream, como revisar los parches de otras personas, reestructurar la
infraestructura del kernel y escribir documentación.
Con ese fin, Technical Advisory Board (TAB) de la Fundación Linux propone
este Modelo de Madurez de Contribución al Kernel de Linux. Estas
expectativas comunes para la participación con la comunidad upstream
tienen como objetivo aumentar la influencia de los desarrolladores
individuales, aumentar la colaboración de las organizaciones y mejorar
la salud general del ecosistema del kernel de Linux.
El TAB insta a las organizaciones a evaluar continuamente su modelo de
madurez de Código Abierto y comprometerse a realizar mejoras para
alinearse con este modelo. Para ser eficaz, esta evaluación debe
incorporar la reacción de toda la organización, incluyendo la gerencia
y los desarrolladores en todos los niveles de antigüedad. En el espíritu
de Código Abierto, alentamos a las organizaciones a publicar sus
evaluaciones y planes para mejorar su participación con la comunidad
upstream.
Nivel 0
=======
* A los ingenieros de software no se les permite contribuir con parches
al kernel de Linux.
Nivel 1
=======
* A los ingenieros de software se les permite contribuir con parches al
kernel de Linux, ya sea como parte de sus responsabilidades de trabajo
o en su propio tiempo.
Nivel 2
=======
* Se espera que los ingenieros de software contribuyan al kernel de Linux
como parte de sus responsabilidades de trabajo.
* Se proporcionará apoyo a los ingenieros de software para asistir a
conferencias relacionadas con Linux como parte de su trabajo.
* Las contribuciones de código upstream de un ingeniero de software se
considerarán en la promoción y las revisiones de rendimiento.
Nivel 3
=======
* Se espera que los ingenieros de software revisen los parches (incluidos
los parches escritos por ingenieros de otras empresas) como parte de
sus responsabilidades de trabajo.
* Contribuir con presentaciones o ponencias a conferencias relacionadas
con Linux o académicas (como las organizadas por la Fundación Linux,
Usenix, ACM, etc.), se consideran parte del trabajo de un ingeniero.
* Las contribuciones a la comunidad de un ingeniero de software se
considerarán en la promoción y las revisiones de rendimiento.
* Las organizaciones informarán regularmente sobre las métricas de sus
contribuciones de código abierto y harán un seguimiento de estas
métricas a lo largo del tiempo. Estas métricas pueden publicarse
solo internamente dentro de la organización, o a discreción de la
organización, algunas o todas pueden publicarse externamente. Las
métricas que se sugieren encarecidamente incluyen:
* El número de contribuciones al kernel upstream por equipo u
organización (por ejemplo, todas las personas que reportan a un
gerente o director o vicepresidente).
* El porcentaje de desarrolladores del kernel que han realizado
contribuciones upstream relativo al total de desarrolladores
del kernel en la organización.
* El intervalo de tiempo entre los kernels utilizados en los servidores
y/o productos de la organización y la fecha de publicación del kernel
upstream en el que se basa el kernel interno.
* El número de commits fuera del árbol de desarrollo presentes en los
kernels internos.
Nivel 4
=======
* Se anima a los ingenieros de software a pasar una parte de su tiempo de
trabajo centrado en el Trabajo Ascendente, que se define como revisar
parches, servir en los comités de programas, mejorar la infraestructura
del proyecto central como escribir o mantener pruebas, reducir la deuda
de tecnología upstream, escribir documentación, etc.
* Los ingenieros de software son apoyados para ayudar a organizar
conferencias relacionadas con Linux.
* Las organizaciones considerarán los comentarios de los miembros de la
comunidad en las revisiones oficiales de rendimiento.
Nivel 5
=======
* El desarrollo del kernel upstream se considera un puesto de trabajo
formal, con al menos un tercio del tiempo del ingeniero pasado a hacer
el Trabajo Ascendente.
* Las organizaciones buscarán activamente las reacciones de los miembros
de la comunidad como un factor en las revisiones oficiales de
rendimiento.
* Las organizaciones informarán regularmente internamente sobre la ratio
de trabajo upstream a trabajo enfocado en perseguir directamente los
objetivos comerciales.
@@ -0,0 +1,381 @@
.. include:: ../disclaimer-sp.rst
:Original: :ref:`Documentation/process/deprecated.rst <deprecated>`
:Translator: Sergio Gonzalez <sergio.collado@gmail.com>
.. _sp_deprecated:
============================================================================
Interfaces obsoletos, Características del lenguaje, Atributos y Convenciones
============================================================================
En un mundo perfecto, sería posible convertir todas las instancias de
alguna API obsoleta en una nueva API y quitar la API anterior en un
único ciclo de desarrollo. Desafortunadamente, debido al tamaño del kernel,
la jerarquía de mantenimiento, y el tiempo, no siempre es posible hacer
estos cambios de una única vez. Esto significa que las nuevas instancias
han de ir creándose en el kernel, mientras que las antiguas se quitan,
haciendo que la cantidad de trabajo para limpiar las APIs crezca. Para
informar a los desarrolladores sobre qué ha sido declarado obsoleto y por
qué, ha sido creada esta lista como un lugar donde indicar cuando los usos
obsoletos son propuestos para incluir en el kernel.
__deprecated
------------
Mientras que este atributo señala visualmente que un interface ha sido
declarado obsoleto, este `no produce más avisos durante las compilaciones
<https://git.kernel.org/linus/771c035372a036f83353eef46dbb829780330234>`_
porque uno de los objetivos del kernel es que compile sin avisos, y
nadie ha hecho nada para quitar estos interfaces obsoletos. Mientras
que usar `__deprecated` es sencillo para anotar una API obsoleta en
un archivo de cabecera, no es la solución completa. Dichos interfaces
deben o bien ser quitados por completo, o añadidos a este archivo para
desanimar a otros a usarla en el futuro.
BUG() y BUG_ON()
----------------
Use WARN() y WARN_ON() en su lugar, y gestione las condiciones de error
"imposibles" tan elegantemente como se pueda. Mientras que la familia de
funciones BUG() fueron originalmente diseñadas para actuar como una
"situación imposible", confirmar y disponer de un hilo del kernel de forma
"segura", estas funciones han resultado ser demasiado arriesgadas. (e.g.
"¿en qué orden se necesitan liberar los locks? ¿Se han restaurado sus
estados?). La popular función BUG() desestabilizará el sistema o lo romperá
totalmente, lo cual hace imposible depurarlo o incluso generar reportes de
crash. Linus tiene una `opinión muy fuerte
<https://lore.kernel.org/lkml/CA+55aFy6jNLsywVYdGp83AMrXBo_P-pkjkphPGrO=82SPKCpLQ@mail.gmail.com/>`_
y sentimientos `sobre esto
<https://lore.kernel.org/lkml/CAHk-=whDHsbK3HTOpTF=ue_o04onRwTEaK_ZoJp_fjbqq4+=Jw@mail.gmail.com/>`_.
Nótese que la familia de funciones WARN() únicamente debería ser usada
en situaciones que se "esperan no sean alcanzables". Si se quiere
avisar sobre situaciones "alcanzables pero no deseadas", úsese la familia
de funciones pr_warn(). Los responsables del sistema pueden haber definido
*panic_on_warn* sysctl para asegurarse que sus sistemas no continúan
ejecutándose en presencia del condiciones "no alcanzables". (Por ejemplo,
véase commits como `este
<https://git.kernel.org/linus/d4689846881d160a4d12a514e991a740bcb5d65a>`_.)
Operaciones aritméticas en los argumentos de reserva de memoria
---------------------------------------------------------------
Los cálculos dinámicos de tamaño (especialmente multiplicaciones) no
deberían realizarse en los argumentos de reserva de memoria (o similares)
debido al riesgo de desbordamiento. Esto puede llevar a valores rotando y
que se realicen reservas de memoria menores que las que se esperaban. El
uso de esas reservas puede llevar a desbordamientos en el 'heap' de memoria
y otros funcionamientos incorrectos. (Una excepción a esto son los valores
literales donde el compilador si puede avisar si estos puede desbordarse.
De todos modos, el método recomendado en estos caso es reescribir el código
como se sugiere a continuación para evitar las operaciones aritméticas en
la reserva de memoria.)
Por ejemplo, no utilice `count * size`` como argumento, como en::
foo = kmalloc(count * size, GFP_KERNEL);
En vez de eso, utilice la reserva con dos argumentos::
foo = kmalloc_array(count, size, GFP_KERNEL);
Específicamente, kmalloc() puede ser sustituido con kmalloc_array(),
kzalloc() puede ser sustituido con kcalloc().
Si no existen funciones con dos argumentos, utilice las funciones que se
saturan, en caso de desbordamiento::
bar = vmalloc(array_size(count, size));
Otro caso común a evitar es calcular el tamaño de una estructura com
la suma de otras estructuras, como en::
header = kzalloc(sizeof(*header) + count * sizeof(*header->item),
GFP_KERNEL);
En vez de eso emplee::
header = kzalloc(struct_size(header, item, count), GFP_KERNEL);
.. note:: Si se usa struct_size() en una estructura que contiene un elemento
de longitud cero o un array de un único elemento como un array miembro,
por favor reescribir ese uso y cambiar a un `miembro array flexible
<#zero-length-and-one-element-arrays>`_
Para otros cálculos, por favor use las funciones de ayuda: size_mul(),
size_add(), and size_sub(). Por ejemplo, en el caso de::
foo = krealloc(current_size + chunk_size * (count - 3), GFP_KERNEL);
Re-escríbase, como::
foo = krealloc(size_add(current_size,
size_mul(chunk_size,
size_sub(count, 3))), GFP_KERNEL);
Para más detalles, mire también array3_size() y flex_array_size(),
como también la familia de funciones relacionadas check_mul_overflow(),
check_add_overflow(), check_sub_overflow(), y check_shl_overflow().
simple_strtol(), simple_strtoll(), simple_strtoul(), simple_strtoull()
----------------------------------------------------------------------
Las funciones: simple_strtol(), simple_strtoll(), simple_strtoul(), y
simple_strtoull() explícitamente ignoran los desbordamientos, lo que puede
llevar a resultados inesperados por las funciones que las llaman. Las
funciones respectivas kstrtol(), kstrtoll(), kstrtoul(), y kstrtoull()
tienden a ser reemplazos correctos, aunque nótese que necesitarán que la
cadena de caracteres termine en NUL o en el carácter de línea nueva.
strcpy()
--------
strcpy() no realiza verificaciones de los límites del buffer de destino.
Esto puede resultar en desbordamientos lineals más allá del fin del buffer,
causando todo tipo de errores. Mientras `CONFIG_FORTIFY_SOURCE=y` otras
varias opciones de compilación reducen el riesgo de usar esta función, no
hay ninguna buena razón para añadir nuevos usos de esta. El remplazo seguro
es la función strscpy(), aunque se ha de tener cuidado con cualquier caso
en el el valor retornado por strcpy() sea usado, ya que strscpy() no
devuelve un puntero a el destino, sino el número de caracteres no nulos
compilados (o el valor negativo de errno cuando se trunca la cadena de
caracteres).
strncpy() en cadenas de caracteres terminadas en NUL
----------------------------------------------------
El uso de strncpy() no garantiza que el buffer de destino esté terminado en
NUL. Esto puede causar varios errores de desbordamiento en lectura y otros
tipos de funcionamiento erróneo debido a que falta la terminación en NUL.
Esta función también termina la cadena de caracteres en NUL en el buffer de
destino si la cadena de origen es más corta que el buffer de destino, lo
cual puede ser una penalización innecesaria para funciones usen esta
función con cadenas de caracteres que sí están terminadas en NUL.
Cuando se necesita que la cadena de destino sea terminada en NUL,
el mejor reemplazo es usar la función strscpy(), aunque se ha de tener
cuidado en los casos en los que el valor de strncpy() fuera usado, ya que
strscpy() no devuelve un puntero al destino, sino el número de
caracteres no nulos copiados (o el valor negativo de errno cuando se trunca
la cadena de caracteres). Cualquier caso restante que necesitase todavía
ser terminado en el caracter nulo, debería usar strscpy_pad().
Si una función usa cadenas de caracteres que no necesitan terminar en NUL,
debería usarse strtomem(), y el destino debería señalarse con el atributo
`__nonstring
<https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html>`_
para evitar avisos futuros en el compilador. Para casos que todavía
necesitan cadenas de caracteres que se rellenen al final con el
caracter NUL, usar strtomem_pad().
strlcpy()
---------
strlcpy() primero lee por completo el buffer de origen (ya que el valor
devuelto intenta ser el mismo que el de strlen()). Esta lectura puede
sobrepasar el límite de tamaño del destino. Esto ineficiente y puede causar
desbordamientos de lectura si la cadena de origen no está terminada en el
carácter NUL. El reemplazo seguro de esta función es strscpy(), pero se ha
de tener cuidado que en los casos en lso que se usase el valor devuelto de
strlcpy(), ya que strscpy() devolverá valores negativos de erno cuando se
produzcan truncados.
Especificación de formato %p
----------------------------
Tradicionalmente,el uso de "%p" en el formato de cadenas de caracteres
resultaría en exponer esas direcciones en dmesg, proc, sysfs, etc. En vez
de dejar que sean una vulnerabilidad, todos los "%p" que se usan en el
kernel se imprimen como un hash, haciéndolos efectivamente inutilizables
para usarlos como direcciones de memoria. Nuevos usos de "%p" no deberían
ser añadidos al kernel. Para textos de direcciones, usar "%pS" es
mejor, ya que resulta en el nombre del símbolo. Para prácticamente el
resto de casos, mejor no usar "%p" en absoluto.
Parafraseando las actuales `direcciones de Linus <https://lore.kernel.org/lkml/CA+55aFwQEd_d40g4mUCSsVRZzrFPUJt74vc6PPpb675hYNXcKw@mail.gmail.com/>`_:
- Si el valor "hasheado" "%p" no tienen ninguna finalidad, preguntarse si el
puntero es realmente importante. ¿Quizás se podría quitar totalmente?
- Si realmente se piensa que el valor del puntero es importante, ¿porqué
algún estado del sistema o nivel de privilegio de usuario es considerado
"especial"? Si piensa que puede justificarse (en comentarios y mensajes
del commit), de forma suficiente como para pasar el escrutinio de Linux,
quizás pueda usar el "%p", a la vez que se asegura que tiene los permisos
correspondientes.
Si está depurando algo donde el "%p" hasheado está causando problemas,
se puede arrancar temporalmente con la opción de depuración "`no_hash_pointers
<https://git.kernel.org/linus/5ead723a20e0447bc7db33dc3070b420e5f80aa6>`_".
Arrays de longitud variable (VLAs)
----------------------------------
Usando VLA en la pila (stack) produce un código mucho peor que los arrays
de tamaño estático. Mientras que estos errores no triviales de `rendimiento
<https://git.kernel.org/linus/02361bc77888>`_ son razón suficiente
para no usar VLAs, esto además son un riesgo de seguridad. El crecimiento
dinámico del array en la pila, puede exceder la memoria restante en
el segmento de la pila. Esto podría llevara a un fallo, posible sobre-escritura
de contenido al final de la pila (cuando se construye sin
`CONFIG_THREAD_INFO_IN_TASK=y`), o sobre-escritura de la memoria adyacente
a la pila (cuando se construye sin `CONFIG_VMAP_STACK=y`).
Switch case fall-through implícito
----------------------------------
El lenguaje C permite a las sentencias 'switch' saltar de un caso al
siguiente caso cuando la sentencia de ruptura "break" no aparece al final
del caso. Esto, introduce ambigüedad en el código, ya que no siempre está
claro si el 'break' que falta es intencionado o un olvido. Por ejemplo, no
es obvio solamente mirando al código si `STATE_ONE` está escrito para
intencionadamente saltar en `STATE_TWO`::
switch (value) {
case STATE_ONE:
do_something();
case STATE_TWO:
do_other();
break;
default:
WARN("unknown state");
}
Ya que ha habido una larga lista de defectos `debidos a declaraciones de "break"
que faltan <https://cwe.mitre.org/data/definitions/484.html>`_, no se
permiten 'fall-through' implícitos. Para identificar 'fall-through'
intencionados, se ha adoptado la pseudo-palabra-clave macro "falltrhrough",
que expande las extensiones de gcc `__attribute__((__fallthrough__))
<https://gcc.gnu.org/onlinedocs/gcc/Statement-Attributes.html>`_.
(Cuando la sintaxis de C17/c18 `[[fallthrough]]` sea más comúnmente
soportadas por los compiladores de C, analizadores estáticos, e IDEs,
se puede cambiar a usar esa sintaxis para esa pseudo-palabra-clave.
Todos los bloques switch/case deben acabar en uno de:
* break;
* fallthrough;
* continue;
* goto <label>;
* return [expression];
Arrays de longitud cero y un elemento
-------------------------------------
Hay una necesidad habitual en el kernel de proveer una forma para declarar
un grupo de elementos consecutivos de tamaño dinámico en una estructura.
El código del kernel debería usar siempre `"miembros array flexible" <https://en.wikipedia.org/wiki/Flexible_array_member>`_
en estos casos. El estilo anterior de arrays de un elemento o de longitud
cero, no deben usarse más.
En el código C más antiguo, los elementos finales de tamaño dinámico se
obtenían especificando un array de un elemento al final de una estructura::
struct something {
size_t count;
struct foo items[1];
};
En código C más antiguo, elementos seguidos de tamaño dinámico eran creados
especificando una array de un único elemento al final de una estructura::
struct something {
size_t count;
struct foo items[1];
};
Esto llevó a resultados incorrectos en los cálculos de tamaño mediante
sizeof() (el cual hubiera necesitado eliminar el tamaño del último elemento
para tener un tamaño correcto de la "cabecera"). Una `extensión de GNU C
<https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html>`_ se empezó a usar
para permitir los arrays de longitud cero, para evitar estos tipos de
problemas de tamaño::
struct something {
size_t count;
struct foo items[0];
};
Pero esto llevó a otros problemas, y no solucionó algunos otros problemas
compartidos por ambos estilos, como no ser capaz de detectar cuando ese array
accidentalmente _no_ es usado al final de la estructura (lo que podía pasar
directamente, o cuando dicha estructura era usada en uniones, estructuras
de estructuras, etc).
C99 introdujo "los arrays miembros flexibles", los cuales carecen de un
tamaño numérico en su declaración del array::
struct something {
size_t count;
struct foo items[];
};
Esta es la forma en la que el kernel espera que se declaren los elementos
de tamaño dinámico concatenados. Esto permite al compilador generar
errores, cuando el array flexible no es declarado en el último lugar de la
estructura, lo que ayuda a prevenir errores en él código del tipo
`comportamiento indefinido <https://git.kernel.org/linus/76497732932f15e7323dc805e8ea8dc11bb587cf>`_.
Esto también permite al compilador analizar correctamente los tamaños de
los arrays (via sizeof(), `CONFIG_FORTIFY_SOURCE`, y `CONFIG_UBSAN_BOUNDS`).
Por ejemplo, si no hay un mecanismo que avise que el siguiente uso de
sizeof() en un array de longitud cero, siempre resulta en cero::
struct something {
size_t count;
struct foo items[0];
};
struct something *instance;
instance = kmalloc(struct_size(instance, items, count), GFP_KERNEL);
instance->count = count;
size = sizeof(instance->items) * instance->count;
memcpy(instance->items, source, size);
En la última línea del código anterior, ``zero`` vale ``cero``, cuando uno
podría esperar que representa el tamaño total en bytes de la memoria dinámica
reservada para el array consecutivo ``items``. Aquí hay un par de ejemplos
más sobre este tema: `link 1
<https://git.kernel.org/linus/f2cd32a443da694ac4e28fbf4ac6f9d5cc63a539>`_,
`link 2
<https://git.kernel.org/linus/ab91c2a89f86be2898cee208d492816ec238b2cf>`_.
Sin embargo, los array de miembros flexibles tienen un type incompleto, y
no se ha de aplicar el operador sizeof()<https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html>`_,
así cualquier mal uso de dichos operadores será detectado inmediatamente en
el momento de compilación.
Con respecto a los arrays de un único elemento, se ha de ser consciente de
que dichos arrays ocupan al menos tanto espacio como un único objeto del
tipo https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html>`_, de ahí que
estos contribuyan al tamaño de la estructura que los contiene. Esto es
proclive a errores cada vez que se quiere calcular el tamaño total de la
memoria dinámica para reservar una estructura que contenga un array de este
tipo como su miembro::
struct something {
size_t count;
struct foo items[1];
};
struct something *instance;
instance = kmalloc(struct_size(instance, items, count - 1), GFP_KERNEL);
instance->count = count;
size = sizeof(instance->items) * instance->count;
memcpy(instance->items, source, size);
En el ejemplo anterior, hemos de recordar calcular ``count - 1``, cuando se
usa la función de ayuda struct_size(), de otro modo estaríamos
--desintencionadamente--reservando memoria para un ``items`` de más. La
forma más clara y menos proclive a errores es implementar esto mediante el
uso de `array miembro flexible`, junto con las funciones de ayuda:
struct_size() y flex_array_size()::
struct something {
size_t count;
struct foo items[];
};
struct something *instance;
instance = kmalloc(struct_size(instance, items, count), GFP_KERNEL);
instance->count = count;
memcpy(instance->items, source, flex_array_size(instance, items, instance->count));
@@ -0,0 +1,32 @@
.. include:: ../disclaimer-sp.rst
:Original: Documentation/process/development-process.rst
:Translator: Carlos Bilbao <carlos.bilbao.osdev@gmail.com> and Avadhut Naik <avadhut.naik@amd.com>
.. _sp_development_process_main:
Guía del proceso de desarrollo del kernel
=========================================
El propósito de este documento es ayudar a los desarrolladores (y sus
jefes) a trabajar con la comunidad de desarrollo con el mínimo de
frustración. Es un intento de documentar cómo funciona esta comunidad
de una manera accesible, para aquellos que no están familiarizados
íntimamente con el desarrollo del kernel Linux (o, de hecho, el desarrollo
de software libre en general). Si bien hay algo de material técnico aquí,
esto es en gran medida una discusión orientada al proceso que no requiere
un conocimiento profundo de la programación del kernel para entenderla.
.. toctree::
:caption: Contenido
:numbered:
:maxdepth: 2
1.Intro
2.Process
3.Early-stage
4.Coding
5.Posting
6.Followthrough
7.AdvancedTopics
8.Conclusion
@@ -0,0 +1,374 @@
.. include:: ../disclaimer-sp.rst
:Original: :ref:`Documentation/process/email-clients.rst <email_clients>`
:Translator: Carlos Bilbao <carlos.bilbao.osdev@gmail.com>
.. _sp_email_clients:
Información de clientes de correo electrónico para Linux
========================================================
Git
---
A día de hoy, la mayoría de los desarrolladores usan ``git send-email`` en
lugar de los clientes de correo electrónico normales. La página de manual
para esto es bastante buena. En la recepción del correo, los maintainers
usan ``git am`` para aplicar los parches.
Si es usted nuevo en ``git`` entonces envíese su primer parche. Guárdelo
como texto sin formato, incluidos todos los encabezados. Ejecute ``git am raw_email.txt``
y luego revise el registro de cambios con ``git log``. Cuando eso funcione,
envíe el parche a la(s) lista(s) de correo apropiada(s).
Preferencias Generales
----------------------
Los parches para el kernel de Linux se envían por correo electrónico,
preferiblemente como texto en línea en el cuerpo del correo electrónico.
Algunos maintainers aceptan archivos adjuntos, pero entonces los archivos
adjuntos deben tener tipo de contenido ``text/plain``. Sin embargo, los
archivos adjuntos generalmente están mal vistos porque hacen que citar
partes del parche sea más difícil durante el proceso de revisión del
parche.
También se recomienda encarecidamente que utilice texto sin formato en el
cuerpo del correo electrónico, para parches y otros correos electrónicos
por igual. https://useplaintext.email puede ser útil para obtener
información sobre cómo configurar su cliente de correo electrónico
preferido, así como una lista de clientes de correo electrónico
recomendados si aún no tiene una preferencia.
Los clientes de correo electrónico que se utilizan para los parches del
kernel Linux deben enviar el texto del parche intacto. Por ejemplo, no
deben modificar ni eliminar pestañas o espacios, incluso al principio o al
final de las líneas.
No envíe parches con ``format=flowed``. Esto puede causar saltos de línea
no deseados e inesperados.
No deje que su cliente de correo electrónico ajuste automáticamente las
palabras por usted. Esto también puede corromper su parche.
Los clientes de correo electrónico no deben modificar la codificación del
de caracteres del texto. Los parches enviados por correo electrónico deben
estar en codificación ASCII o UTF-8 únicamente. Si configura su cliente de
correo electrónico para enviar correos electrónicos con codificación UTF-8,
evite algunos posibles problemas con los caracteres.
Los clientes de correo electrónico deben generar y mantener los
encabezados "References:" o "In-Reply-To:" para que el hilo de correo no
se rompa.
Copiar y pegar (o cortar y pegar) generalmente no funciona para los
parches, porque las tabulaciones se convierten en espacios. Utilizar
xclipboard, xclip y/o xcutsel puede funcionar, pero es mejor probarlo usted
mismo o simplemente evitar copiar y pegar.
No utilice firmas PGP/GPG en el correo que contiene parches.
Esto rompe muchos scripts que leen y aplican los parches.
(Esto debería ser reparable.)
Es una buena idea enviarse un parche a sí mismo, guardar el mensaje
recibido, y aplicarlo con éxito con 'patch' antes de enviar el parche a las
listas de correo de Linux.
Algunas sugerencias para el cliente de correo electrónico (MUA)
---------------------------------------------------------------
Aquí hay algunos consejos específicos de configuración de MUA para editar y
enviar parches para el kernel de Linux. Estos no pretenden cubrir todo
detalle de configuración de los paquetes de software.
Leyenda:
- TUI = text-based user interface (interfaz de usuario basada en texto)
- GUI = graphical user interface (interfaz de usuario gráfica)
Alpine (TUI)
************
Opciones de configuración:
En la sección :menuselection:`Sending Preferences`:
- :menuselection: `Do Not Send Flowed Text` debe estar ``enabled``
- :menuselection:`Strip Whitespace Before Sending` debe estar ``disabled``
Al redactar el mensaje, el cursor debe colocarse donde el parche debería
aparecer, y luego presionando `CTRL-R` se le permite especificar e
archivo de parche a insertar en el mensaje.
Claws Mail (GUI)
****************
Funciona. Algunos usan esto con éxito para los parches.
Para insertar un parche haga :menuselection:`Message-->Insert File` (`CTRL-I`)
o use un editor externo.
Si el parche insertado debe editarse en la ventana de composición de Claws
"Auto wrapping" en
:menuselection:`Configuration-->Preferences-->Compose-->Wrapping` debe
permanecer deshabilitado.
Evolution (GUI)
***************
Algunos usan esto con éxito para sus parches.
Cuando escriba un correo seleccione: Preformat
desde :menuselection:`Format-->Paragraph Style-->Preformatted` (`CTRL-7`)
o en la barra de herramientas
Luego haga:
:menuselection:`Insert-->Text File...` (`ALT-N x`)
para insertar el parche.
También puede hacer ``diff -Nru old.c new.c | xclip``, seleccione
:menuselection:`Preformat`, luego pege con el boton del medio.
Kmail (GUI)
***********
Algunos usan Kmail con éxito para los parches.
La configuración predeterminada de no redactar en HTML es adecuada; no haga
cambios en esto.
Al redactar un correo electrónico, en las opciones, desmarque "word wrap".
La única desventaja es que cualquier texto que escriba en el correo
electrónico no se ajustará a cada palabra, por lo que tendrá que ajustar
manualmente el texto antes del parche. La forma más fácil de evitar esto es
redactar su correo electrónico con Word Wrap habilitado, luego guardar
como borrador. Una vez que lo vuelva a sacar de sus borradores, estará
envuelto por palabras y puede desmarcar "word wrap" sin perder el existente
texto.
En la parte inferior de su correo electrónico, coloque el delimitador de
parche de uso común antes de insertar su parche: tres guiones (``---``).
Luego desde la opción de menu :menuselection:`Message` seleccione
:menuselection:`insert file` y busque su parche.
De forma adicional, puede personalizar el menú de la barra de herramientas
de creación de mensajes y poner el icono :menuselection:`insert file`.
Haga que la ventana del editor sea lo suficientemente ancha para que no se
envuelva ninguna línea. A partir de KMail 1.13.5 (KDE 4.5.4), KMail
aplicará ajuste de texto al enviar el correo electrónico si las líneas se
ajustan en la ventana del redactor. Tener ajuste de palabras deshabilitado
en el menú Opciones no es suficiente. Por lo tanto, si su parche tiene
líneas muy largas, debe hacer que la ventana del redactor sea muy amplia
antes de enviar el correo electrónico. Consulte: https://bugs.kde.org/show_bug.cgi?id=174034
You can safely GPG sign attachments, but inlined text is preferred for
patches so do not GPG sign them. Signing patches that have been inserted
as inlined text will make them tricky to extract from their 7-bit encoding.
Puede firmar archivos adjuntos con GPG de forma segura, pero se prefiere el
texto en línea para parches, así que no los firme con GPG. Firmar parches
que se han insertado como texto en línea hará que sea difícil extraerlos de
su codificación de 7 bits.
Si es absolutamente necesario enviar parches como archivos adjuntos en
lugar de como texto en línea, haga clic con el botón derecho en el archivo
adjunto y seleccione :menuselection:`properties`, y luego
:menuselection:`Suggest automatic display` para hacer que el archivo
adjunto esté en línea para que sea más visible.
Al guardar parches que se envían como texto en línea, seleccione el correo
electrónico que contiene el parche del panel de la lista de mensajes, haga
clic con el botón derecho y seleccione :menuselection:`save as`. Puede usar
todo el correo electrónico sin modificar como un parche de estar bien
compuesto. Los correos electrónicos se guardan como lectura y escritura
solo para el usuario, por lo que tendrá que cambiarlos para que sean
legibles en grupo y en todo el mundo si copia estos en otro lugar.
Notas de Lotus (GUI)
********************
Huya de este.
IBM Verse (Web GUI)
*******************
Vea notas sobre Lotus.
Mutt (TUI)
**********
Muchos desarrolladores de Linux usan ``mutt``, por lo que debe funcionar
bastante bien.
Mutt no viene con un editor, por lo que cualquier editor que use debe ser
utilizado de forma que no haya saltos de línea automáticos. La mayoría de
los editores tienen una opción :menuselection:`insert file` que inserta el
contenido de un archivo inalterado.
Para usar ``vim`` con mutt::
set editor="vi"
Si utiliza xclip, escriba el comando::
:set paste
antes del boton del medio o shift-insert o use::
:r filename
si desea incluir el parche en línea.
(a)ttach (adjuntar) funciona bien sin ``set paste``.
También puedes generar parches con ``git format-patch`` y luego usar Mutt
para enviarlos::
$ mutt -H 0001-some-bug-fix.patch
Opciones de configuración:
Debería funcionar con la configuración predeterminada.
Sin embargo, es una buena idea establecer ``send_charset`` en:
set send_charset="us-ascii:utf-8"
Mutt es altamente personalizable. Aquí tiene una configuración mínima para
empezar a usar Mutt para enviar parches a través de Gmail::
# .muttrc
# ================ IMAP ====================
set imap_user = 'suusuario@gmail.com'
set imap_pass = 'sucontraseña'
set spoolfile = imaps://imap.gmail.com/INBOX
set folder = imaps://imap.gmail.com/
set record="imaps://imap.gmail.com/[Gmail]/Sent Mail"
set postponed="imaps://imap.gmail.com/[Gmail]/Drafts"
set mbox="imaps://imap.gmail.com/[Gmail]/All Mail"
# ================ SMTP ====================
set smtp_url = "smtp://username@smtp.gmail.com:587/"
set smtp_pass = $imap_pass
set ssl_force_tls = yes # Requerir conexión encriptada
# ================ Composición ====================
set editor = `echo \$EDITOR`
set edit_headers = yes # Ver los encabezados al editar
set charset = UTF-8 # valor de $LANG; also fallback for send_charset
# El remitente, la dirección de correo electrónico y la línea de firma deben coincidir
unset use_domain # Porque joe@localhost es simplemente vergonzoso
set realname = "SU NOMBRE"
set from = "username@gmail.com"
set use_from = yes
Los documentos Mutt tienen mucha más información:
https://gitlab.com/muttmua/mutt/-/wikis/UseCases/Gmail
http://www.mutt.org/doc/manual/
Pine (TUI)
**********
Pine ha tenido algunos problemas de truncamiento de espacios en blanco en
el pasado, pero estos todo debería estar arreglados ahora.
Use alpine (sucesor de pino) si puede.
Opciones de configuración:
- ``quell-flowed-text`` necesitado para versiones actuales
- la opción ``no-strip-whitespace-before-send`` es necesaria
Sylpheed (GUI)
**************
- Funciona bien para insertar texto (o usar archivos adjuntos).
- Permite el uso de un editor externo.
- Es lento en carpetas grandes.
- No realizará la autenticación TLS SMTP en una conexión que no sea SSL.
- Tiene una útil barra de reglas en la ventana de redacción.
- Agregar direcciones a la libreta de direcciones no las muestra
adecuadamente.
Thunderbird (GUI)
*****************
Thunderbird es un clon de Outlook al que le gusta alterar el texto, pero
hay formas para obligarlo a comportarse.
Después de hacer las modificaciones, que incluye instalar las extensiones,
necesita reiniciar Thunderbird.
- Permitir el uso de un editor externo:
Lo más fácil de hacer con Thunderbird y los parches es usar extensiones
que abran su editor externo favorito.
Aquí hay algunas extensiones de ejemplo que son capaces de hacer esto.
- "External Editor Revived"
https://github.com/Frederick888/external-editor-revived
https://addons.thunderbird.net/en-GB/thunderbird/addon/external-editor-revived/
Requiere instalar un "native messaging host".
Por favor, lea la wiki que se puede encontrar aquí:
https://github.com/Frederick888/external-editor-revived/wiki
- "External Editor"
https://github.com/exteditor/exteditor
Para hacer esto, descargue e instale la extensión, luego abra la ventana
:menuselection:`compose`, agregue un botón para ello usando
:menuselection:`View-->Toolbars-->Customize...`
luego simplemente haga clic en el botón nuevo cuando desee usar el editor
externo.
Tenga en cuenta que "External Editor" requiere que su editor no haga
fork, o en otras palabras, el editor no debe regresar antes de cerrar.
Es posible que deba pasar flags adicionales o cambiar la configuración
de su editor. En particular, si está utilizando gvim, debe pasar la
opción -f a gvim poniendo ``/usr/bin/gvim --nofork"`` (si el binario
está en ``/usr/bin``) al campo del editor de texto en los ajustes
:menuselection:`external editor`. Si está utilizando algún otro editor,
lea su manual para saber cómo hacer esto.
Para sacarle algo de sentido al editor interno, haga esto:
- Edite sus ajustes de configuración de Thunderbird para que no utilice ``format=flowed``!
Vaya a su ventana principal y busque el botón de su menú desplegable principal.
:menuselection:`Main Menu-->Preferences-->General-->Config Editor...`
para abrir el editor de registro de Thunderbird.
- Seleccione ``mailnews.send_plaintext_flowed`` como ``false``
- Seleccione ``mailnews.wraplength`` de ``72`` a ``0``
- ¡No escriba mensajes HTML! Acuda a la ventana principal
:menuselection:`Main Menu-->Account Settings-->youracc@server.something-->Composition & Addressing`!
Ahí puede deshabilitar la opción "Compose messages in HTML format".
- ¡Abra mensajes solo como texto sin formato! Acuda a la ventana principal
:menuselection:`Main Menu-->View-->Message Body As-->Plain Text`!
TkRat (GUI)
***********
Funciona. Utilice "Insert file..." o un editor externo.
Gmail (Web GUI)
***************
No funciona para enviar parches.
El cliente web de Gmail convierte las tabulaciones en espacios automáticamente.
Al mismo tiempo, envuelve líneas cada 78 caracteres con saltos de línea de
estilo CRLF aunque el problema de tab2space se puede resolver con un editor
externo.
Otro problema es que Gmail codificará en base64 cualquier mensaje que tenga
un carácter no ASCII. Eso incluye cosas como nombres europeos.
@@ -0,0 +1,341 @@
.. SPDX-License-Identifier: GPL-2.0
.. include:: ../disclaimer-sp.rst
:Original: Documentation/process/embargoed-hardware-issues.rst
:Translator: Avadhut Naik <avadhut.naik@amd.com>
Problemas de hardware embargados
================================
Alcance
-------
Los problemas de hardware que resultan en problemas de seguridad son una
categoría diferente de errores de seguridad que los errores de software
puro que solo afectan al kernel de Linux.
Los problemas de hardware como Meltdown, Spectre, L1TF, etc. deben
tratarse de manera diferente porque usualmente afectan a todos los
sistemas operativos (“OS”) y, por lo tanto, necesitan coordinación entre
vendedores diferentes de OS, distribuciones, vendedores de hardware y
otras partes. Para algunos de los problemas, las mitigaciones de software
pueden depender de actualizaciones de microcódigo o firmware, los cuales
necesitan una coordinación adicional.
.. _Contacto:
Contacto
--------
El equipo de seguridad de hardware del kernel de Linux es separado del
equipo regular de seguridad del kernel de Linux.
El equipo solo maneja la coordinación de los problemas de seguridad de
hardware embargados. Los informes de errores de seguridad de software puro
en el kernel de Linux no son manejados por este equipo y el "reportero"
(quien informa del error) será guiado a contactar el equipo de seguridad
del kernel de Linux (:doc:`errores de seguridad <security-bugs>`) en su
lugar.
El equipo puede contactar por correo electrónico en
<hardware-security@kernel.org>. Esta es una lista privada de oficiales de
seguridad que lo ayudarán a coordinar un problema de acuerdo con nuestro
proceso documentado.
La lista esta encriptada y el correo electrónico a la lista puede ser
enviado por PGP o S/MIME encriptado y debe estar firmado con la llave de
PGP del reportero o el certificado de S/MIME. La llave de PGP y el
certificado de S/MIME de la lista están disponibles en las siguientes
URLs:
- PGP: https://www.kernel.org/static/files/hardware-security.asc
- S/MIME: https://www.kernel.org/static/files/hardware-security.crt
Si bien los problemas de seguridad del hardware a menudo son manejados por
el vendedor de hardware afectado, damos la bienvenida al contacto de
investigadores o individuos que hayan identificado una posible falla de
hardware.
Oficiales de seguridad de hardware
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
El equipo actual de oficiales de seguridad de hardware:
- Linus Torvalds (Linux Foundation Fellow)
- Greg Kroah-Hartman (Linux Foundation Fellow)
- Thomas Gleixner (Linux Foundation Fellow)
Operación de listas de correo
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Las listas de correo encriptadas que se utilizan en nuestro proceso están
alojados en la infraestructura de IT de la Fundación Linux. Al proporcionar
este servicio, los miembros del personal de operaciones de IT de la
Fundación Linux técnicamente tienen la capacidad de acceder a la
información embargada, pero están obligados a la confidencialidad por su
contrato de trabajo. El personal de IT de la Fundación Linux también es
responsable para operar y administrar el resto de la infraestructura de
kernel.org.
El actual director de infraestructura de proyecto de IT de la Fundación
Linux es Konstantin Ryabitsev.
Acuerdos de no divulgación
--------------------------
El equipo de seguridad de hardware del kernel de Linux no es un organismo
formal y, por lo tanto, no puede firmar cualquier acuerdo de no
divulgación. La comunidad del kernel es consciente de la naturaleza
delicada de tales problemas y ofrece un Memorando de Entendimiento en su
lugar.
Memorando de Entendimiento
--------------------------
La comunidad del kernel de Linux tiene una comprensión profunda del
requisito de mantener los problemas de seguridad de hardware bajo embargo
para la coordinación entre diferentes vendedores de OS, distribuidores,
vendedores de hardware y otras partes.
La comunidad del kernel de Linux ha manejado con éxito los problemas de
seguridad del hardware en el pasado y tiene los mecanismos necesarios para
permitir el desarrollo compatible con la comunidad bajo restricciones de
embargo.
La comunidad del kernel de Linux tiene un equipo de seguridad de hardware
dedicado para el contacto inicial, el cual supervisa el proceso de manejo
de tales problemas bajo las reglas de embargo.
El equipo de seguridad de hardware identifica a los desarrolladores
(expertos en dominio) que formarán el equipo de respuesta inicial para un
problema en particular. El equipo de respuesta inicial puede involucrar
más desarrolladores (expertos en dominio) para abordar el problema de la
mejor manera técnica.
Todos los desarrolladores involucrados se comprometen a adherirse a las
reglas del embargo y a mantener confidencial la información recibida. La
violación de la promesa conducirá a la exclusión inmediata del problema
actual y la eliminación de todas las listas de correo relacionadas.
Además, el equipo de seguridad de hardware también excluirá al
delincuente de problemas futuros. El impacto de esta consecuencia es un
elemento de disuasión altamente efectivo en nuestra comunidad. En caso de
que ocurra una violación, el equipo de seguridad de hardware informará a
las partes involucradas inmediatamente. Si usted o alguien tiene
conocimiento de una posible violación, por favor, infórmelo inmediatamente
a los oficiales de seguridad de hardware.
Proceso
^^^^^^^
Debido a la naturaleza distribuida globalmente del desarrollo del kernel
de Linux, las reuniones cara a cara hacen imposible abordar los
problemas de seguridad del hardware. Las conferencias telefónicas son
difíciles de coordinar debido a las zonas horarias y otros factores y
solo deben usarse cuando sea absolutamente necesario. El correo
electrónico encriptado ha demostrado ser el método de comunicación más
efectivo y seguro para estos tipos de problemas.
Inicio de la divulgación
""""""""""""""""""""""""
La divulgación comienza contactado al equipo de seguridad de hardware del
kernel de Linux por correo electrónico. Este contacto inicial debe
contener una descripción del problema y una lista de cualquier hardware
afectado conocido. Si su organización fabrica o distribuye el hardware
afectado, le animamos a considerar también que otro hardware podría estar
afectado.
El equipo de seguridad de hardware proporcionará una lista de correo
encriptada específica para el incidente que se utilizará para la discusión
inicial con el reportero, la divulgación adicional y la coordinación.
El equipo de seguridad de hardware proporcionará a la parte reveladora una
lista de desarrolladores (expertos de dominios) a quienes se debe informar
inicialmente sobre el problema después de confirmar con los
desarrolladores que se adherirán a este Memorando de Entendimiento y al
proceso documentado. Estos desarrolladores forman el equipo de respuesta
inicial y serán responsables de manejar el problema después del contacto
inicial. El equipo de seguridad de hardware apoyará al equipo de
respuesta, pero no necesariamente involucrandose en el proceso de desarrollo
de mitigación.
Si bien los desarrolladores individuales pueden estar cubiertos por un
acuerdo de no divulgación a través de su empleador, no pueden firmar
acuerdos individuales de no divulgación en su papel de desarrolladores
del kernel de Linux. Sin embargo, aceptarán adherirse a este proceso
documentado y al Memorando de Entendimiento.
La parte reveladora debe proporcionar una lista de contactos para todas
las demás entidades ya que han sido, o deberían ser, informadas sobre el
problema. Esto sirve para varios propósitos:
- La lista de entidades divulgadas permite la comunicación en toda la
industria, por ejemplo, otros vendedores de OS, vendedores de HW, etc.
- Las entidades divulgadas pueden ser contactadas para nombrar a expertos
que deben participar en el desarrollo de la mitigación.
- Si un experto que se requiere para manejar un problema es empleado por
una entidad cotizada o un miembro de una entidad cotizada, los equipos
de respuesta pueden solicitar la divulgación de ese experto a esa
entidad. Esto asegura que el experto también forme parte del equipo de
respuesta de la entidad.
Divulgación
"""""""""""
La parte reveladora proporcionará información detallada al equipo de
respuesta inicial a través de la lista de correo encriptada especifica.
Según nuestra experiencia, la documentación técnica de estos problemas
suele ser un punto de partida suficiente y es mejor hacer aclaraciones
técnicas adicionales a través del correo electrónico.
Desarrollo de la mitigación
"""""""""""""""""""""""""""
El equipo de respuesta inicial configura una lista de correo encriptada o
reutiliza una existente si es apropiada.
El uso de una lista de correo está cerca del proceso normal de desarrollo
de Linux y se ha utilizado con éxito en el desarrollo de mitigación para
varios problemas de seguridad de hardware en el pasado.
La lista de correo funciona en la misma manera que el desarrollo normal de
Linux. Los parches se publican, discuten y revisan y, si se acuerda, se
aplican a un repositorio git no público al que solo pueden acceder los
desarrolladores participantes a través de una conexión segura. El
repositorio contiene la rama principal de desarrollo en comparación con
el kernel principal y las ramas backport para versiones estables del
kernel según sea necesario.
El equipo de respuesta inicial identificará a más expertos de la
comunidad de desarrolladores del kernel de Linux según sea necesario. La
incorporación de expertos puede ocurrir en cualquier momento del proceso
de desarrollo y debe manejarse de manera oportuna.
Si un experto es empleado por o es miembro de una entidad en la lista de
divulgación proporcionada por la parte reveladora, entonces se solicitará
la participación de la entidad pertinente.
Si no es así, entonces se informará a la parte reveladora sobre la
participación de los expertos. Los expertos están cubiertos por el
Memorando de Entendimiento y se solicita a la parte reveladora que
reconozca la participación. En caso de que la parte reveladora tenga una
razón convincente para objetar, entonces esta objeción debe plantearse
dentro de los cinco días laborables y resolverse con el equipo de
incidente inmediatamente. Si la parte reveladora no reacciona dentro de
los cinco días laborables, esto se toma como un reconocimiento silencioso.
Después del reconocimiento o la resolución de una objeción, el experto es
revelado por el equipo de incidente y se incorpora al proceso de
desarrollo.
Lanzamiento coordinado
""""""""""""""""""""""
Las partes involucradas negociarán la fecha y la hora en la que termina el
embargo. En ese momento, las mitigaciones preparadas se integran en los
árboles de kernel relevantes y se publican.
Si bien entendemos que los problemas de seguridad del hardware requieren
un tiempo de embargo coordinado, el tiempo de embargo debe limitarse al
tiempo mínimo que se requiere para que todas las partes involucradas
desarrollen, prueben y preparen las mitigaciones. Extender el tiempo de
embargo artificialmente para cumplir con las fechas de discusión de la
conferencia u otras razones no técnicas está creando más trabajo y carga
para los desarrolladores y los equipos de respuesta involucrados, ya que
los parches necesitan mantenerse actualizados para seguir el desarrollo en
curso del kernel upstream, lo cual podría crear cambios conflictivos.
Asignación de CVE
"""""""""""""""""
Ni el equipo de seguridad de hardware ni el equipo de respuesta inicial
asignan CVEs, ni se requieren para el proceso de desarrollo. Si los CVEs
son proporcionados por la parte reveladora, pueden usarse con fines de
documentación.
Embajadores del proceso
-----------------------
Para obtener asistencia con este proceso, hemos establecido embajadores
en varias organizaciones, que pueden responder preguntas o proporcionar
orientación sobre el proceso de reporte y el manejo posterior. Los
embajadores no están involucrados en la divulgación de un problema en
particular, a menos que lo solicite un equipo de respuesta o una parte
revelada involucrada. La lista de embajadores actuales:
============= ========================================================
AMD Tom Lendacky <thomas.lendacky@amd.com>
Ampere Darren Hart <darren@os.amperecomputing.com>
ARM Catalin Marinas <catalin.marinas@arm.com>
IBM Power Anton Blanchard <anton@linux.ibm.com>
IBM Z Christian Borntraeger <borntraeger@de.ibm.com>
Intel Tony Luck <tony.luck@intel.com>
Qualcomm Trilok Soni <quic_tsoni@quicinc.com>
Samsung Javier González <javier.gonz@samsung.com>
Microsoft James Morris <jamorris@linux.microsoft.com>
Xen Andrew Cooper <andrew.cooper3@citrix.com>
Canonical John Johansen <john.johansen@canonical.com>
Debian Ben Hutchings <ben@decadent.org.uk>
Oracle Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Red Hat Josh Poimboeuf <jpoimboe@redhat.com>
SUSE Jiri Kosina <jkosina@suse.cz>
Google Kees Cook <keescook@chromium.org>
LLVM Nick Desaulniers <ndesaulniers@google.com>
============= ========================================================
Si quiere que su organización se añada a la lista de embajadores, por
favor póngase en contacto con el equipo de seguridad de hardware. El
embajador nominado tiene que entender y apoyar nuestro proceso
completamente y está idealmente bien conectado en la comunidad del kernel
de Linux.
Listas de correo encriptadas
----------------------------
Usamos listas de correo encriptadas para la comunicación. El principio de
funcionamiento de estas listas es que el correo electrónico enviado a la
lista se encripta con la llave PGP de la lista o con el certificado S/MIME
de la lista. El software de lista de correo descifra el correo electrónico
y lo vuelve a encriptar individualmente para cada suscriptor con la llave
PGP del suscriptor o el certificado S/MIME. Los detalles sobre el software
de la lista de correo y la configuración que se usa para asegurar la
seguridad de las listas y la protección de los datos se pueden encontrar
aquí: https://korg.wiki.kernel.org/userdoc/remail.
Llaves de lista
^^^^^^^^^^^^^^^
Para el contacto inicial, consulte :ref:`Contacto`. Para las listas de
correo especificas de incidentes, la llave y el certificado S/MIME se
envían a los suscriptores por correo electrónico desde la lista
especifica.
Suscripción a listas específicas de incidentes
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
La suscripción es manejada por los equipos de respuesta. Las partes
reveladas que quieren participar en la comunicación envían una lista de
suscriptores potenciales al equipo de respuesta para que el equipo de
respuesta pueda validar las solicitudes de suscripción.
Cada suscriptor necesita enviar una solicitud de suscripción al equipo de
respuesta por correo electrónico. El correo electrónico debe estar firmado
con la llave PGP del suscriptor o el certificado S/MIME. Si se usa una
llave PGP, debe estar disponible desde un servidor de llave publica y esta
idealmente conectada a la red de confianza PGP del kernel de Linux. Véase
también: https://www.kernel.org/signature.html.
El equipo de respuesta verifica que la solicitud del suscriptor sea válida
y añade al suscriptor a la lista. Después de la suscripción, el suscriptor
recibirá un correo electrónico de la lista que está firmado con la llave
PGP de la lista o el certificado S/MIME de la lista. El cliente de correo
electrónico del suscriptor puede extraer la llave PGP o el certificado
S/MIME de la firma, de modo que el suscriptor pueda enviar correo
electrónico encriptado a la lista.
@@ -0,0 +1,797 @@
.. include:: ../disclaimer-sp.rst
:Translator: Sergio González Collado <sergio.collado@gmail.com>
.. _sp_handling_regressions:
Gestión de regresiones
++++++++++++++++++++++
*No causamos regresiones* -- este documento describe la que es la "primera
regla del desarrollo del kernel de Linux" y que implica en la práctica para
los desarrolladores. Y complementa la documentación:
Documentation/admin-guide/reporting-regressions.rst, que cubre el tema
desde el punto de vista de un usuario; si nunca ha leído ese texto, realice
al menos una lectura rápida del mismo antes de continuar.
Las partes importantes (el "TL;DR")
===================================
#. Asegúrese de que los suscriptores a la lista `regression mailing list
<https://lore.kernel.org/regressions/>`_ (regressions@lists.linux.dev)
son conocedores con rapidez de cualquier nuevo informe de regresión:
* Cuando se reciba un correo que no incluyó a la lista, inclúyalo en la
conversación de los correos, mandando un breve "Reply-all" con la
lista en CCed.
* Mande o redirija cualquier informe originado en los gestores de bugs
a la lista.
#. Haga que el bot del kernel de Linux "regzbot" realice el seguimiento del
incidente (esto es opcional, pero recomendado).
* Para reportes enviados por correo, verificar si contiene alguna línea
como ``#regzbot introduced v5.13..v5.14-rc1``. Si no, mandar una
respuesta (con la lista de regresiones en CC) que contenga un párrafo
como el siguiente, lo que le indica a regzbot cuando empezó a suceder
el incidente::
#regzbot ^introduced 1f2e3d4c5b6a
* Cuando se mandan informes desde un gestor de incidentes a la lista de
regresiones(ver más arriba), incluir un párrafo como el siguiente::
#regzbot introduced: v5.13..v5.14-rc1
#regzbot from: Some N. Ice Human <some.human@example.com>
#regzbot monitor: http://some.bugtracker.example.com/ticket?id=123456789
#. Cuando se manden correcciones para las regresiones, añadir etiquetas
"Link:" a la descripción, apuntado a todos los sitios donde se informó
del incidente, como se indica en el documento:
Documentation/process/submitting-patches.rst y
:ref:`Documentation/process/5.Posting.rst <development_posting>`.
#. Intente arreglar las regresiones rápidamente una vez la causa haya sido
identificada; las correcciones para la mayor parte de las regresiones
deberían ser integradas en menos de dos semanas, pero algunas pueden
resolverse en dos o tres días.
Detalles importantes para desarrolladores en la regresiones de kernel de Linux
==============================================================================
Puntos básicos importantes más en detalle
-----------------------------------------
Qué hacer cuando se recibe un aviso de regresión.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Asegúrese de que el programa de gestión de regresiones del kernel de Linux
y los subscritos a la lista de correo `regression mailing list
<https://lore.kernel.org/regressions/>`_ (regressions@lists.linux.dev) son
conocedores de cualquier nuevo informe de regresión:
* Cuando se recibe un informe por email que no tiene en CC la lista,
inmediatamente meterla en el la cadena de emails mandado al menos un
breve "Reply-all" con la lista en CC; Intentar asegurar que la lista es
añadida en CC de nuevo en caso de que alguna respuesta la omita de la
lista.
* Si un informe enviado a un gestor de defectos, llega a su correo,
reenvíelo o redirijalo a la lista. Considere verificar los archivos de
la lista de antemano, si la persona que lo ha informado, lo ha enviado
anteriormente, como se indica en:
Documentation/admin-guide/reporting-issues.rst.
Cuando se realice cualquiera de las acciones anteriores, considere
inmediatamente iniciar el seguimiento de la regresión con "regzbot" el
gestor de regresiones del kernel de Linux.
* Para los informes enviados por email, verificar si se ha incluido un
comando a "regzbot", como ``#regzbot introduced 1f2e3d4c5b6a``. Si no es
así, envíe una respuesta (con la lista de regresiones en CC) con un
párrafo como el siguiente::
#regzbot ^introduced: v5.13..v5.14-rc1
Esto indica a regzbot el rango de versiones en el cual es defecto
comenzó a suceder; Puede especificar un rango usando los identificadores
de los commits así como un único commit, en caso en el que el informante
haya identificado el commit causante con 'bisect'.
Tenga en cuenta que el acento circunflejo (^) antes de "introduced":
Esto indica a regzbot, que debe tratar el email padre (el que ha sido
respondido) como el informeinicial para la regresión que quiere ser
seguida. Esto es importante, ya que regzbot buscará más tarde parches
con etiquetas "Link:" que apunten al al informe de losarchivos de
lore.kernel.org.
* Cuando mande informes de regresiones a un gestor de defectos, incluya un
párrafo con los siguientes comandos a regzbot::
#regzbot introduced: 1f2e3d4c5b6a
#regzbot from: Some N. Ice Human <some.human@example.com>
#regzbot monitor: http://some.bugtracker.example.com/ticket?id=123456789
Regzbot asociará automáticamente parches con el informe que contengan
las etiquetas "Link:" apuntando a su email o el ticket indicado.
Qué es importante cuando se corrigen regresiones
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
No se necesita hacer nada especial cuando se mandan las correcciones para
las regresiones únicamente recordar lo que se explica en los documentos:
Documentation/process/submitting-patches.rst,
:ref:`Documentation/process/5.Posting.rst <development_posting>`, y
Documentation/process/stable-kernel-rules.rst
* Apunte a todos los lugares donde el incidente se reportó usando la
etiqueta "Link:" ::
Link: https://lore.kernel.org/r/30th.anniversary.repost@klaava.Helsinki.FI/
Link: https://bugzilla.kernel.org/show_bug.cgi?id=1234567890
* Añada la etiqueta "Fixes:" para indicar el commit causante de la
regresión.
* Si el culpable ha sido "mergeado" en un ciclo de desarrollo anterior,
marque explícitamente el fix para retro-importarlo usando la etiqueta
``Cc: stable@vger.kernel.org`` tag.
Todo esto se espera y es importante en una regresión, ya que estas
etiquetas son de gran valor para todos (incluido usted) que pueda estar
mirando en ese incidente semanas, meses o años después. Estas etiquetas son
también cruciales para las herramientas y scripts usados por otros
desarrolladores del kernel o distribuciones de Linux; una de esas
herramientas es regzbot, el cual depende mucho de las etiquetas "Link:"
para asociar los informes por regresiones con los cambios que las
resuelven.
Priorización del trabajo en arreglar regresiones
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Al final, los desarrolladores deberían hacer lo posible para evitar a los
usuarios situaciones donde una regresión les deje solo tres opciones:
* Ejecutar el kernel con una regresión que afecta seriamente al uso.
* Cambiar a un kernel nuevo o mas antiguo -- rebajarse a una versión
soportada del kernel que no tenga las funcionalidades requeridas.
* Continuar ejecutando una versión desfasada y potencialmente insegura del
kernel por más de dos semanas después de que el causante de una regresión
fuese identificado.
Cómo se ejecuta esto depende mucho de la situación. A continuación se
presentan unas reglas generales, en orden de importancia:
* Priorice el trabajo en la gestión de los informes de la regresión y
arreglar la regresión por encima de cualquier otro trabajo en el kernel
de Linux, a menos que lo último afecte profundamente a efectos de
seguridad, o cause errores en los que haya pérdida o daño de datos.
* Considere siempre revertir los commits responsables y re-aplicarlos
después, junto con las correcciones necesarias, ya que esto puede la
forma menos peligrosa y más rápida de arreglar la regresión.
* Los desarrolladores deberían gestionar la regresión en todos los kernels
soportados de la serie, pero son libres de delegar el trabajo al equipo
permanente el incidente no hubiese ocurrido en la línea principal.
* Intente resolver cualquier regresión que apareciera en el ciclo de
desarrollo antes de que este acabe. Si se teme que una corrección
pudiera ser demasiado arriesgada para aplicarla días antes de una
liberación de la línea principal de desarrollo, dejar decidir a Linus:
mande la corrección a él de forma separada, tan pronto como sea posible
con una explicación de la situación. El podrá decidir, y posponer la
liberación si fuese necesario, por ejemplo si aparecieran múltiples
cambios como ese.
* Gestione las regresiones en la rama estable, de largo término, o la
propia rama principal de las versiones, con más urgencia que la
regresiones en las preliberaciones. Esto cambia después de la liberación
de la quinta pre-liberación, aka "-rc5": la rama principal entonces se
vuelve más importante, asegurar que todas las mejoras y correcciones son
idealmente testeados juntos por al menos una semana antes de que Linux
libere la nueva versión en la rama principal.
* Intente arreglar regresiones en un intervalo de una semana después de
que se ha identificado el responsable, si el incidente fue introducido
en alguno de los siguientes casos:
* una versión estable/largo-plazo reciente
* en el último ciclo de desarrollo de la rama principal
En el último caso (por ejemplo v5.14), intentar gestionar las
regresiones incluso más rápido, si la versión estable precedente (v5.13)
ha de ser abandonada pronto o ya se ha etiquetado como de final de vida
(EOL de las siglas en inglés End-of-Life) -- esto sucede usualmente
sobre tres o cuatro semanas después de una liberación de una versión en
la rama principal.
* Intente arreglar cualquier otra regresión en un periodo de dos semanas
después de que el culpable haya sido identificado. Dos o tres semanas
adicionales son aceptables para regresiones de rendimiento y otros
incidentes que son molestos, pero no bloquean a nadie la ejecución de
Linux (a menos que se un incidente en el ciclo de desarrollo actual, en
ese caso se debería gestionar antes de la liberación de la versión).
Unas semanas son aceptables si la regresión únicamente puede ser
arreglada con un cambio arriesgado y al mismo tiempo únicamente afecta a
unos pocos usuarios; también está bien si se usa tanto tiempo como fuera
necesario si la regresión está presente en la segunda versión más nueva
de largo plazo del kernel.
Nota: Los intervalos de tiempo mencionados anteriormente para la resolución
de las regresiones, incluyen la verificación de esta, revisión e inclusión
en la rama principal, idealmente con la corrección incluida en la rama
"linux-next" al menos brevemente. Esto conllevará retrasos que también se
tienen tener en cuenta.
Se espera que los maintainers de los subsistemas, ayuden en conseguir esos
tiempos, haciendo revisiones con prontitud y gestionando con rapidez los
parches aceptados. Esto puede resultar en tener que mandar peticiones de
git-pull antes o de forma más frecuente que lo normal; dependiendo del
arreglo, podría incluso ser aceptable saltarse la verificación en
linux-next. Especialmente para las correcciones en las ramas de los kernels
estable y de largo plazo necesitan ser gestionadas rápidamente, y las
correcciones necesitan ser incluidas en la rama principal antes de que
puedan ser incluidas posteriormente a las series precedentes.
Más aspectos sobre regresiones que los desarrolladores deben saber
------------------------------------------------------------------
Cómo tratar con cambios donde se sabe que hay riesgo de regresión
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Evalué cómo de grande es el riesgo de una regresión, por ejemplo realizando
una búsqueda en las distribuciones de linux y en Git forges. Considere
también preguntar a otros desarrolladores o proyectos que pudieran ser
afectados para evaluar o incluso testear el cambio propuesto; si
apareciesen problemas, quizás se pudiera encontrar una solución aceptable
para todos.
Si al final, el riesgo de la regresión parece ser relativamente pequeño,
entonces adelante con el cambio, pero siempre informe a todas las partes
involucradas del posible riesgo. Por tanto, asegúrese de que la descripción
del parche, se hace explícito este hecho. Una vez el cambio ha sido
integrado, informe al gestor de regresiones de Linux y a las listas de
correo de regresiones sobre el riesgo, de manera que cualquiera que tenga
el cambio en el radar, en el caso de que aparezcan reportes. Dependiendo
del riesgo, quizás se quiera preguntar al mantenedor del subsistema, que
mencione el hecho en su línea principal de desarrollo.
¿Qué más hay que saber sobre regresiones?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Repase la documentación: Documentation/admin-guide/reporting-regressions.rst,
esta cubre otros aspectos a tener a en cuenta y conocer:
* la finalidad de la "regla de no regresión"
* qué incidencias no se califican como regresión
* quién es el responsable de identificar la causa raíz de una regresión
* cómo gestionar situaciones difíciles, como por ejemplo cuando una
regresión es causada por una corrección de seguridad o cuando una
regresión causa otra regresión
A quién preguntar por consejo cuando se trata de regresiones
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Mande un email a la lista de correo de regresiones
(regressions@lists.linux.dev) y CC al seguidor de regresiones del kernel de
Linux (regressions@leemhuis.info); Si el incidente pudiera ser mejor
gestionarlo en privado, puede omitirse la lista.
Más sobre la gestión de regresiones con regzbot
-----------------------------------------------
¿Por qué el kernel de Linux tiene un gestor de regresiones, y por qué se usa regzbot?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Reglas como "no regresiones" necesitan asegurar que se cumplen, de otro
modo se romperían accidentalmente o a propósito. La historia ha mostrado
que esto es verdad también para el kernel de Linux. Esto es por lo que
Thorsten Leemhuis se ofreció como voluntario para dar una solución a esto,
con el gestor de regresiones del kernel de Linux. A nadie se le paga por
hacer esto, y esa es la razón por la gestión de regresiones es un servicio
con el "mejor esfuerzo".
Intentos iniciales de gestionar manualmente las regresiones han demostrado
que es una tarea extenuante y frustrante, y por esa razón se dejaron de
hacer después de un tiempo. Para evitar que volviese a suceder esto,
Thorsten desarrollo regbot para facilitar el trabajo, con el objetivo a
largo plazo de automatizar la gestión de regresiones tanto como fuese
posible para cualquiera que estuviese involucrado.
¿Cómo funciona el seguimiento de regresiones con regzbot?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
El bot monitoriza las respuestas de los informes de las regresiones
identificadas. Adicionalmente mira si se han publicado o enviado parches
que hagan referencia a esos informes con la etiqueta: "Link:"; respuestas a
esos parches también se siguen. Combinando esta información, también
proporciona una buena imagen del estado actual del proceso de corrección.
Regzbot intenta hacer todo este trabajo con tan poco retraso como sea
posible tanto para la gente que lo reporta, como para los desarrolladores.
De hecho, solo los informantes son requeridos para una tarea adicional:
necesitan informar a regzbot con el comando ``#regzbot introduced``
indicado anteriormente; si no hacen esto, alguien más puede hacerlo usando
``#regzbot ^introduced``.
Para los desarrolladores normalmente no hay un trabajo adicional que
realizar, únicamente necesitan asegurarse una cosa, que ya se hacía mucho
antes de que regzbot apareciera: añadir las etiquetas "Link:" a la
descripción del parche apuntando a todos los informes sobre el error
corregido.
¿Tengo que usar regzbot?
~~~~~~~~~~~~~~~~~~~~~~~~
Hacerlo es por el bien de todo el mundo, tanto los mantenedores del kernel,
como Linus Torvalds dependen parcialmente en regzbot para seguir su trabajo
-- por ejemplo cuando deciden liberar una nueva versión o ampliar la fase de
desarrollo. Para esto necesitan conocer todas las regresiones que están sin
corregir; para esto, es conocido que Linux mira los informes semanales que
manda regzbot.
¿He de informar a regzbot cada regresión que encuentre?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Idealmente, sí: todos somos humanos y olvidamos fácilmente los problemas
cuando algo más importante aparece inesperadamente -- por ejemplo un
problema mayor en el kernel de Linux o algo en la vida real que nos mantenga
alejados de los teclados por un tiempo. Por eso es mejor informar a regzbot
sobre cada regresión, excepto cuando inmediatamente escribimos un parche y
los mandamos al árbol de desarrollo en el que se integran habitualmente a
la serie del kernel.
¿Cómo ver qué regresiones esta siguiendo regbot actualmente?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Verifique el `interfaz web de regzbot <https://linux-regtracking.leemhuis.info/regzbot/>`_
para ver la última información; o `busque el último informe de regresiones
<https://lore.kernel.org/lkml/?q=%22Linux+regressions+report%22+f%3Aregzbot>`_,
el cual suele ser enviado por regzbot una vez a la semana el domingo por la
noche (UTC), lo cual es unas horas antes de que Linus normalmente anuncie
las "(pre-)releases".
¿Qué sitios supervisa regzbot?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Regzbot supervisa las listas de correo más importantes de Linux, como
también las de los repositorios linux-next, mainline y stable/longterm.
¿Qué tipos de incidentes han de ser monitorizados por regzbot?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
El bot debe hacer seguimiento de las regresiones, y por tanto por favor,
no involucre a regzbot para incidencias normales. Pero es correcto para
el gestor de incidencias de kernel de Linux, monitorizar incidentes
graves, como informes sobre cuelgues, corrupción de datos o errores
internos (Panic, Oops, BUG(), warning, ...).
¿Puedo añadir una regresión detectada por un sistema de CI al seguimiento de regzbot?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Siéntase libre de hacerlo, si la regresión en concreto puede tener un
impacto en casos de uso prácticos y por tanto ser detectado por los usuarios;
Así, por favor no involucre a regzbot en regresiones teóricas que
difícilmente pudieran manifestarse en un uso real.
¿Cómo interactuar con regzbot?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Usando el comando 'regzbot' en una respuesta directa o indirecta al correo
con el informe de regresión. Ese comando necesita estar en su propio
párrafo (debe estar separado del resto del texto usando líneas en blanco):
Por ejemplo ``#regzbot introduced <version or commit>``, que hace que regzbot
considere el correo como un informe de regressión que se ha de añadir al
seguimiento, como se ha descrito anteriormente; ``#regzbot ^introduced <version or commit>``
es otro ejemplo del comando, el cual indica a regzbot que considere el email
anterior como el informe de una regresión que se ha de comenzar a monitorizar.
Una vez uno de esos dos comandos se ha utilizado, se pueden usar otros
comandos regzbot en respuestas directas o indirectas al informe. Puede
escribirlos debajo de uno de los comandos anteriormente usados o en las
respuestas al correo en el que se uso como respuesta a ese correo:
* Definir o actualizar el título::
#regzbot title: foo
* Monitorizar una discusión o un tiquet de bugzilla.kernel.org donde
aspectos adicionales del incidente o de la corrección se están
comentando -- por ejemplo presentar un parche que corrige la regresión::
#regzbot monitor: https://lore.kernel.org/all/30th.anniversary.repost@klaava.Helsinki.FI/
Monitorizar solamente funciona para lore.kernel.org y bugzilla.kernel.org;
regzbot considerará todos los mensajes en ese hilo o el tiquet como
relacionados al proceso de corrección.
* Indicar a un lugar donde más detalles de interés, como un mensaje en una
lista de correo o un tiquet en un gestor de incidencias que pueden estar
levemente relacionados, pero con un tema diferente::
#regzbot link: https://bugzilla.kernel.org/show_bug.cgi?id=123456789
* Identificar una regresión como corregida por un commit que se ha mandado
aguas arriba o se ha publicado::
#regzbot fixed-by: 1f2e3d4c5d
* Identificar una regresión como un duplicado de otra que ya es seguida
por regzbot::
#regzbot dup-of: https://lore.kernel.org/all/30th.anniversary.repost@klaava.Helsinki.FI/
* Identificar una regresión como inválida::
#regzbot invalid: wasn't a regression, problem has always existed
¿Algo más que decir sobre regzbot y sus comandos?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Hay información más detallada y actualizada sobre el bot de seguimiento de
regresiones del kernel de Linux en: `project page <https://gitlab.com/knurd42/regzbot>`_,
y entre otros contiene una `guia de inicio <https://gitlab.com/knurd42/regzbot/-/blob/main/docs/getting_started.md>`_
y `documentación de referencia <https://gitlab.com/knurd42/regzbot/-/blob/main/docs/reference.md>`_
Ambos contienen más detalles que las secciones anteriores.
Citas de Linus sobre regresiones
--------------------------------
A continuación se encuentran unos ejemplos reales (traducidos) de como
Linus Torvalds espera que se gestionen las regresiones:
* De 2017-10-26 (1/2)
<https://lore.kernel.org/lkml/CA+55aFwiiQYJ+YoLKCXjN_beDVfu38mg=Ggg5LFOcqHE8Qi7Zw@mail.gmail.com/>`_::
Si rompes la configuración de los espacios de usuario ESO ES UNA REGRESIÓN.
No está bien decir "pero nosotros arreglaremos la configuración del espacio
de usuario".
Realmente. NO ESTÁ BIEN.
[...]
La primera regla es:
- no causamos regresiones
y el corolario es que cuando una regresión pasa, lo admitimos y lo
arreglamos, en vez de echar la culpa al espacio de usuario.
El hecho de que aparentemente se haya negado la regresión durante
tres semanas, significa que lo revertiré y dejaré de integrar peticiones
de apparmor hasta que la gente involucrada entienda como se hace
el desarrollo del kernel.
* De `2017-10-26 (2/2)
<https://lore.kernel.org/lkml/CA+55aFxW7NMAMvYhkvz1UPbUTUJewRt6Yb51QAx5RtrWOwjebg@mail.gmail.com/>`_::
La gente debería sentirse libre de actualizar su kernel y simplemente
no preocuparse por ello.
Me niego a imponer una limitación del tipo "solo puede actualizar
el kernel si actualiza otro programa". Si el kernel trabaja para tí,
la regla es que continúe trabajando para tí.
Ha habido algunas excepciones, pero son pocas y separadas entre sí, y
generalmente tienen una razón fundamental para haber sucedido, que era
básicamente inevitable, y la gente intentó evitarlas por todos los
medios. Quizás no podamos mantener el hardware más, después de que han
pasado décadas y nadie los usacon kernel modernos. Quizás haya un
problema de seguridad serio con cómo hicimos las cosas, y la gente
depende de un modelo fundamentalmente roto. Quizás haya algún otro roto
fundamental, que tenga que tener una _flag_ y por razones internas y
fundamentales.
Y nótese que esto trata sobre *romper* los entornos de la gente.
Cambios de comportamiento pasan, y quizás no se mantengan algunas
funcionalidades más. Hay un número de campos en /proc/<pid>/stat que
se imprimen como ceros, simplemente porque ni siquiera existen ya en
kernel, o porque mostrarlos era un error (típica una fuga de
información). Pero los números se sustituyeron por ceros, así que
el código que se usaba para parsear esos campos todavía existe. El
usuario puede no ver todo lo que podía ver antes, y por eso el
omportamiento es claramente diferente, pero las cosas todavía
_funcionan_, incluso si no se puede mostrar información sensible
(o que no es ya importante).
Pero si algo realmente se rompe, entonces el cambio debe de arreglarse
o revertirse. Y se arregla en el *kernel*. No diciendo "bueno, arreglaremos
tu espacio de usuario". Ha sido un cambio en el kernel el que creo
el problema, entonces ha de ser el kernel el que lo corrija, porque
tenemos un modelo de "actualización". Pero no tenemos una "actualización
con el nuevo espacio de usuario".
Y yo seriamente me negaré a coger código de gente que no entiende y
honre esta sencilla regla.
Y esta regla no va a cambiar.
Y sí, me doy cuenta que el kernel es "especial" en este respecto. Y
estoy orgulloso de ello.
Y he visto, y puedo señalar, muchos proyectos que dicen "Tenemos que
romper ese caso de uso para poder hacer progresos" o "estabas basandote
en comportamientos no documentados, debe ser duro ser tú" o "hay una
forma mejor de hacer lo que quieres hacer, y tienes que cambiar a esa
nueva forma", y yo simplemente no pienso que eso sea aceptable fuera
de una fase alfa muy temprana que tenga usuarios experimentales que
saben a lo que se han apuntado. El kernel no ha estado en esta
situación en las dos últimas décadas.
Nosotros rompemos la API _dentro_ del kernel todo el tiempo. Y
arreglaremos los problemas internos diciendo "tú ahora necesitas
hacer XYZ", pero entonces es sobre la API interna del kernel y la
gente que hace esto entonces tendrá obviamente que arreglar todos
los usos de esa API del kernel. Nadie puede decir "ahora, yo he roto
la API que usas, y ahora tú necesitas arreglarlo". Quién rompa algo,
lo arregla también.
Y nosotros, simplemente, no rompemos el espacio de usuario.
* De `2020-05-21
<https://lore.kernel.org/all/CAHk-=wiVi7mSrsMP=fLXQrXK_UimybW=ziLOwSzFTtoXUacWVQ@mail.gmail.com/>`_::
Las reglas sobre regresiones nunca han sido sobre ningún tipo de
comportamiento documentado, o dónde está situado el código.
Las reglas sobre regresiones son siempre sobre "roturas en el
flujo de trabajo del usuario".
Los usuarios son literalmente la _única_ cosa que importa.
Argumentaciones como "no debería haber usado esto" o "ese
comportamiento es indefinido, es su culpa que su aplicación no
funcione" o "eso solía funcionar únicamente por un bug del kernel" son
irrelevantes.
Ahora, la realidad nunca es blanca o negra. Así hemos tenido situaciones
como "un serio incidente de seguridad" etc que solamente nos fuerza
a hacer cambios que pueden romper el espacio de usuario. Pero incluso
entonces la regla es que realmente no hay otras opciones para que
las cosas sigan funcionando.
Y obviamente, si los usuarios tardan años en darse cuenta que algo
se ha roto, o si hay formas adecuadas para sortear la rotura que
no causen muchos problemas para los usuarios (por ejemplo: "hay un
puñado de usuarios, y estos pueden usar la línea de comandos del
kernel para evitarlos"; ese tipo de casos), en esos casos se ha sido
un poco menos estricto.
Pero no, "eso que está documentado que está roto" (si es dado a que
el código estaba en preparación o porque el manual dice otra cosa) eso
es irrelevante. Si preparar el código es tan útil que la gente,
acaba usando, esto implica que básicamente es código del kernel con
una señal diciendo "por favor limpiar esto".
El otro lado de la moneda es que la gente que habla sobre "estabilidad
de las APIs" están totalmente equivocados. Las APIs tampoco importan.
Se puede hacer cualquier cambio que se quiera a una API ... siempre y
cuando nadie se de cuenta.
De nuevo, la regla de las regresiones no trata sobre la documentación,
tampoco sobre las APIs y tampoco sobre las fases de la Luna.
Únicamente trata sobre "hemos causado problemas al espacio de usuario que
antes funcionaba".
* De `2017-11-05
<https://lore.kernel.org/all/CA+55aFzUvbGjD8nQ-+3oiMBx14c_6zOj2n7KLN3UsJ-qsd4Dcw@mail.gmail.com/>`_::
Y nuestra regla sobre las regresiones nunca ha sido "el comportamiento
no cambia". Eso podría significar que nunca podríamos hacer ningún
cambio.
Por ejemplo, hacemos cosas como añadir una nueva gestión de
errores etc todo el tiempo, con lo cual a veces incluso añadimos
tests en el directorio de kselftest.
Así que claramente cambia el comportamiento todo el tiempo y
nosotros no consideramos eso una regresión per se.
La regla para regresiones para el kernel es para cuando se
rompe algo en el espacio de usuario. No en algún test. No en
"mira, antes podía hacer X, y ahora no puedo".
* De `2018-08-03
<https://lore.kernel.org/all/CA+55aFwWZX=CXmWDTkDGb36kf12XmTehmQjbiMPCqCRG2hi9kw@mail.gmail.com/>`_::
ESTÁS OLVIDANDO LA REGLA #1 DEL KERNEL.
No hacemos regresiones, y no hacemos regresiones porque estás 100%
equivocado.
Y la razón que apuntas en tú opinión es exactamente *PORQUÉ* estás
equivocado.
Tus "buenas razones" son honradas y pura basura.
El punto de "no hacemos regresiones" es para que la gente pueda
actualizar el kernel y nunca tengan que preocuparse por ello.
> El kernel tiene un bug que ha de ser arreglado
Eso es *TOTALMENTE* insustancial.
Chicos, si algo estaba roto o no, NO IMPORTA.
¿Porqué?
Los errores pasan. Eso es un hecho de la vida. Discutir que
"tenemos que romper algo porque estábamos arreglando un error" es
una locura. Arreglamos decenas de errores cada dia, pensando que
"arreglando un bug" significa que podemos romper otra cosa es algo
que simplemente NO ES VERDAD.
Así que los bugs no son realmente relevantes para la discusión. Estos
suceden y se detectan, se arreglan, y no tienen nada que ver con
"rompemos a los usuarios".
Porque la única cosa que importa ES EL USUARIO.
¿Cómo de complicado es eso de comprender?
Cualquier persona que use "pero no funcionaba correctamente" es
un argumento no tiene la razón. Con respecto al USUARIO, no era
erróneo - funcionaba para él/ella.
Quizás funcionaba *porque* el usuario había tenido el bug en cuenta,
y quizás funcionaba porque el usuario no lo había notado - de nuevo
no importa. Funcionaba para el usuario.
Romper el flujo del trabajo de un usuario, debido a un "bug" es la
PEOR razón que se pueda usar.
Es básicamente decir "He cogido algo que funcionaba, y lo he roto,
pero ahora es mejor". ¿No ves que un argumento como este es j*didamente
absurdo?
y sin usuarios, tu programa no es un programa, es una pieza de
código sin finalidad que puedes perfectamente tirar a la basura.
Seriamente. Esto es *porque* la regla #1 para el desarrollo del
kernel es "no rompemos el espacio de usuario". Porque "He arreglado
un error" PARA NADA ES UN ARGUMENTO si esa corrección del código
rompe el espacio de usuario.
si actualizamos el kernel TODO EL TIEMPO, sin actualizar ningún otro
programa en absoluto. Y esto es absolutamente necesario, porque
las dependencias son terribles.
Y esto es necesario simplemente porque yo como desarrollador del
kernel no actualizo al azar otras herramientas que ni siquiera me
importan como desarrollador del kernel, y yo quiero que mis usuarios
se sientan a salvo haciendo lo mismo.
Así que no. Tu regla está COMPLETAMENTE equivocada. Si no puedes
actualizar el kernel sin actualizar otro binario al azar, entonces
tenemos un problema.
* De `2021-06-05
<https://lore.kernel.org/all/CAHk-=wiUVqHN76YUwhkjZzwTdjMMJf_zN4+u7vEJjmEGh3recw@mail.gmail.com/>`_::
NO HAY ARGUMENTOS VÁLIDOS PARA UNA REGRESIÓN.
Honestamente, la gente de seguridad necesita entender que "no funciona"
no es un caso de éxito sobre seguridad. Es un caso de fallo.
Sí, "no funciona" puede ser seguro. Pero en este caso es totalmente
inutil.
* De `2011-05-06 (1/3)
<https://lore.kernel.org/all/BANLkTim9YvResB+PwRp7QTK-a5VNg2PvmQ@mail.gmail.com/>`_::
La compatibilidad de los binarios es más importante.
Y si los binarios no usan el interfaz para parsear el formato
(o justamente lo parsea incorrectamente - como el reciente ejemplo
de añadir uuid al /proc/self/mountinfo), entonces es una regresión.
Y las regresiones se revierten, a menos que haya problemas de
seguridad o similares que nos hagan decir "Dios mío, realmente
tenemos que romper las cosas".
No entiendo porqué esta simple lógica es tan difícil para algunos
desarrolladores del kernel. La realidad importa. Sus deseos personales
NO IMPORTAN NADA.
Si se crea un interface que puede usarse sin parsear la
descripción del interface, entonces estaḿos atascados en el interface.
La teoría simplemente no importa.
Podrias alludar a arreglar las herramientas, e intentar evitar los
errores de compatibilidad de ese modo. No hay tampoco tantos de esos.
De `2011-05-06 (2/3)
<https://lore.kernel.org/all/BANLkTi=KVXjKR82sqsz4gwjr+E0vtqCmvA@mail.gmail.com/>`_::
Esto claramente NO es un tracepoint interno. Por definición. Y está
siendo usado por powertop.
De `2011-05-06 (3/3)
<https://lore.kernel.org/all/BANLkTinazaXRdGovYL7rRVp+j6HbJ7pzhg@mail.gmail.com/>`_::
Tenemos programas que usan esa ABI y si eso se rompe eso es una
regresión.
* De `2012-07-06 <https://lore.kernel.org/all/CA+55aFwnLJ+0sjx92EGREGTWOx84wwKaraSzpTNJwPVV8edw8g@mail.gmail.com/>`_::
> Ahora esto me ha dejado preguntandome si Debian _inestable_
realmente califica
> como espacio de usuario estándar.
Oh, si el kernel rompe algún espacio de usuario estándar, eso cuenta.
Muchísima gente usa Debian inestable.
* De `2019-09-15
<https://lore.kernel.org/lkml/CAHk-=wiP4K8DRJWsCo=20hn_6054xBamGKF2kPgUzpB5aMaofA@mail.gmail.com/>`_::
Una reversión _en particular_ en el último minuto en el último commit
(no teniendo en cuenta el propio cambio de versión) justo antes
de la liberación, y aunque es bastante incómodo, quizás también es
instructivo.
Lo que es instructivo sobre esto es que he revertido un commit que no
tenía ningún error. De hecho, hacía exactamente lo que pretendía, y lo
hacía muy bien. De hecho lo hacía _tan_ bien que los muy mejorados
patrones de IO que causaba han acabado revelando una regresión observable
desde el espacio de usuario, debido a un error real en un componente
no relacionado en absoluto.
De todas maneras, los detalles actuales de esta regresión no son la
razón por la que señalo esto como instructivo. Es más que es un ejemplo
ilustrativo sobre lo que cuenta como una regresión, y lo que conlleva
la regla del kernel de "no regresiones". El commit que ha sido revertido
no cambiaba ninguna API, y no introducía ningún error nuevo en el código.
Pero acabó exponiendo otro problema, y como eso causaba que la
actualización del kernel fallara para el usuario. Así que ha sido
revertido.
El foco aquí, es que hemos hecho la reversión basándonos en el
comportamiento reportado en el espacio de usuario, no basado en
conceptos como "cambios de ABI" o "provocaba un error". Los mejores
patrones de IO que se han presentado debido al cambio únicamente han
expuesto un viejo error, y la gente ya dependía del benigno
comportamiento de ese viejo error.
Y que no haya miedo, reintroduciremos el arreglo que mejoraba los
patrones de IO una vez hayamos decidido cómo gestionar el hecho de
que hay una interacción incorrecta con un interfaz en el que la
gente dependía de ese comportamiento previo. Es únicamente que
tenemos que ver cómo gestionamos y cómo lo hacemos (no hay menos de
tres parches diferentes de tres desarrolladores distintos que estamos
evaluando, ... puede haber más por llegar). Mientras tanto, he
revertido lo que exponía el problema a los usuarios de esta release,
incluso cuando espero que el fix será reintroducido (quizás insertado
a posteriormente como un parche estable) una vez lleguemos a un
acuerdo sobre cómo se ha de exponer el error.
Lo que hay que recordar de todo el asunto no es sobre si el cambio
de kernel-espacio-de-usuario ABI, o la corrección de un error, o si
el código antiguo "en primer lugar nunca debería haber estado ahí".
Es sobre si algo rompe el actual flujo de trabajo del usuario.
De todas formas, esto era mi pequeña aclaración en todo este
tema de la regresión. Ya que es la "primera regla de la programación
del kernel", me ha parecido que quizás es bueno mencionarlo de
vez en cuando.
@@ -0,0 +1,617 @@
.. include:: ../disclaimer-sp.rst
:Original: :ref:`Documentation/process/howto.rst <process_howto>`
:Translator: Carlos Bilbao <carlos.bilbao.osdev@gmail.com>
.. _sp_process_howto:
Cómo participar en el desarrollo del kernel de Linux
====================================================
Este documento es el principal punto de partida. Contiene instrucciones
sobre cómo convertirse en desarrollador del kernel de Linux y explica cómo
trabajar con el y en su desarrollo. El documento no tratará ningún aspecto
técnico relacionado con la programación del kernel, pero le ayudará
guiándole por el camino correcto.
Si algo en este documento quedara obsoleto, envíe parches al maintainer de
este archivo, que se encuentra en la parte superior del documento.
Introducción
------------
¿De modo que quiere descubrir como convertirse en un/a desarrollador/a del
kernel de Linux? Tal vez su jefe le haya dicho, "Escriba un driver de
Linux para este dispositivo." El objetivo de este documento en enseñarle
todo cuanto necesita para conseguir esto, describiendo el proceso por el
que debe pasar, y con indicaciones de como trabajar con la comunidad.
También trata de explicar las razones por las cuales la comunidad trabaja
de la forma en que lo hace.
El kernel esta principalmente escrito en C, con algunas partes que son
dependientes de la arquitectura en ensamblador. Un buen conocimiento de C
es necesario para desarrollar en el kernel. Lenguaje ensamblador (en
cualquier arquitectura) no es necesario excepto que planee realizar
desarrollo de bajo nivel para dicha arquitectura. Aunque no es un perfecto
sustituto para una educación sólida en C y/o años de experiencia, los
siguientes libros sirven, como mínimo, como referencia:
- "The C Programming Language" de Kernighan e Ritchie [Prentice Hall]
- "Practical C Programming" de Steve Oualline [O'Reilly]
- "C: A Reference Manual" de Harbison and Steele [Prentice Hall]
El kernel está escrito usando GNU C y la cadena de herramientas GNU. Si
bien se adhiere al estándar ISO C89, utiliza una serie de extensiones que
no aparecen en dicho estándar. El kernel usa un C independiente de entorno,
sin depender de la biblioteca C estándar, por lo que algunas partes del
estándar C no son compatibles. Divisiones de long long arbitrarios o
de coma flotante no son permitidas. En ocasiones, puede ser difícil de
entender las suposiciones que el kernel hace respecto a la cadena de
herramientas y las extensiones que usa, y desafortunadamente no hay
referencia definitiva para estas. Consulte las páginas de información de
gcc (`info gcc`) para obtener información al respecto.
Recuerde que está tratando de aprender a trabajar con una comunidad de
desarrollo existente. Es un grupo diverso de personas, con altos estándares
de código, estilo y procedimiento. Estas normas han sido creadas a lo
largo del tiempo en función de lo que se ha encontrado que funciona mejor
para un equipo tan grande y geográficamente disperso. Trate de aprender
tanto como le sea posible acerca de estos estándares antes de tiempo, ya
que están bien documentados; no espere que la gente se adapte a usted o a
la forma de hacer las cosas en su empresa.
Cuestiones legales
------------------
El código fuente del kernel de Linux se publica bajo licencia GPL. Por
favor, revise el archivo COPYING, presente en la carpeta principal del
código fuente, para detalles de la licencia. Si tiene alguna otra pregunta
sobre licencias, contacte a un abogado, no pregunte en listas de discusión
del kernel de Linux. La gente en estas listas no son abogadas, y no debe
confiar en sus opiniones en materia legal.
Para preguntas y respuestas más frecuentes sobre la licencia GPL, consulte:
https://www.gnu.org/licenses/gpl-faq.html
Documentación
--------------
El código fuente del kernel de Linux tiene una gran variedad de documentos
que son increíblemente valiosos para aprender a interactuar con la
comunidad del kernel. Cuando se agregan nuevas funciones al kernel, se
recomienda que se incluyan nuevos archivos de documentación que expliquen
cómo usar la función. Cuando un cambio en el kernel hace que la interfaz
que el kernel expone espacio de usuario cambie, se recomienda que envíe la
información o un parche en las páginas del manual que expliquen el cambio
a mtk.manpages@gmail.com, y CC la lista linux-api@vger.kernel.org.
Esta es la lista de archivos que están en el código fuente del kernel y son
de obligada lectura:
:ref:`Documentation/admin-guide/README.rst <readme>`
Este archivo ofrece una breve descripción del kernel de Linux y
describe lo que es necesario hacer para configurar y compilar el
kernel. Quienes sean nuevos en el kernel deben comenzar aquí.
:ref:`Documentation/process/changes.rst <changes>`
Este archivo proporciona una lista de los niveles mínimos de varios
paquetes que son necesarios para construir y ejecutar el kernel
exitosamente.
:ref:`Documentation/process/coding-style.rst <codingstyle>`
Esto describe el estilo de código del kernel de Linux y algunas de los
razones detrás de esto. Se espera que todo el código nuevo siga las
directrices de este documento. La mayoría de los maintainers solo
aceptarán parches si se siguen estas reglas, y muchas personas solo
revisan el código si tiene el estilo adecuado.
:ref:`Documentation/process/submitting-patches.rst <submittingpatches>`
Este archivo describe en gran detalle cómo crear con éxito y enviar un
parche, que incluye (pero no se limita a):
- Contenidos del correo electrónico (email)
- Formato del email
- A quien se debe enviar
Seguir estas reglas no garantiza el éxito (ya que todos los parches son
sujetos a escrutinio de contenido y estilo), pero en caso de no seguir
dichas reglas, el fracaso es prácticamente garantizado.
Otras excelentes descripciones de cómo crear parches correctamente son:
"The Perfect Patch"
https://www.ozlabs.org/~akpm/stuff/tpp.txt
"Linux kernel patch submission format"
https://web.archive.org/web/20180829112450/http://linux.yyz.us/patch-format.html
:ref:`Documentation/process/stable-api-nonsense.rst <stable_api_nonsense>`
Este archivo describe la lógica detrás de la decisión consciente de
no tener una API estable dentro del kernel, incluidas cosas como:
- Capas intermedias del subsistema (por compatibilidad?)
- Portabilidad de drivers entre sistemas operativos
- Mitigar el cambio rápido dentro del árbol de fuentes del kernel (o
prevenir cambios rápidos)
Este documento es crucial para comprender la filosofía del desarrollo
de Linux y es muy importante para las personas que se mudan a Linux
tras desarrollar otros sistemas operativos.
:ref:`Documentation/process/security-bugs.rst <securitybugs>`
Si cree que ha encontrado un problema de seguridad en el kernel de
Linux, siga los pasos de este documento para ayudar a notificar a los
desarrolladores del kernel y ayudar a resolver el problema.
:ref:`Documentation/process/management-style.rst <managementstyle>`
Este documento describe cómo operan los maintainers del kernel de Linux
y los valores compartidos detrás de sus metodologías. Esta es una
lectura importante para cualquier persona nueva en el desarrollo del
kernel (o cualquier persona que simplemente sienta curiosidad por
el campo IT), ya que clarifica muchos conceptos erróneos y confusiones
comunes sobre el comportamiento único de los maintainers del kernel.
:ref:`Documentation/process/stable-kernel-rules.rst <stable_kernel_rules>`
Este archivo describe las reglas sobre cómo se suceden las versiones
del kernel estable, y qué hacer si desea obtener un cambio en una de
estas publicaciones.
:ref:`Documentation/process/kernel-docs.rst <kernel_docs>`
Una lista de documentación externa relativa al desarrollo del kernel.
Por favor consulte esta lista si no encuentra lo que están buscando
dentro de la documentación del kernel.
:ref:`Documentation/process/applying-patches.rst <applying_patches>`
Una buena introducción que describe exactamente qué es un parche y cómo
aplicarlo a las diferentes ramas de desarrollo del kernel.
El kernel también tiene una gran cantidad de documentos que pueden ser
generados automáticamente desde el propio código fuente o desde
ReStructuredText markups (ReST), como este. Esto incluye un descripción
completa de la API en el kernel y reglas sobre cómo manejar cerrojos
(locking) correctamente.
Todos estos documentos se pueden generar como PDF o HTML ejecutando::
make pdfdocs
make htmldocs
respectivamente desde el directorio fuente principal del kernel.
Los documentos que utilizan el markup ReST se generarán en
Documentation/output. También se pueden generar en formatos LaTeX y ePub
con::
make latexdocs
make epubdocs
Convertirse en un/a desarrollador/a de kernel
---------------------------------------------
Si no sabe nada sobre el desarrollo del kernel de Linux, debería consultar
el proyecto Linux KernelNewbies:
https://kernelnewbies.org
Consiste en una útil lista de correo donde puede preguntar casi cualquier
tipo de pregunta básica de desarrollo del kernel (asegúrese de buscar en
los archivos primero, antes de preguntar algo que ya ha sido respondido en
el pasado.) También tiene un canal IRC que puede usar para hacer preguntas
en tiempo real, y una gran cantidad de documentación útil para ir
aprendiendo sobre el desarrollo del kernel de Linux.
El sitio web tiene información básica sobre la organización del código,
subsistemas, y proyectos actuales (tanto dentro como fuera del árbol).
También describe alguna información logística básica, como cómo compilar
un kernel y aplicar un parche.
Si no sabe por dónde quiere empezar, pero quieres buscar alguna tarea que
comenzar a hacer para unirse a la comunidad de desarrollo del kernel,
acuda al proyecto Linux Kernel Janitor:
https://kernelnewbies.org/KernelJanitors
Es un gran lugar para comenzar. Describe una lista de problemas
relativamente simples que deben limpiarse y corregirse dentro del código
fuente del kernel de Linux árbol de fuentes. Trabajando con los
desarrolladores a cargo de este proyecto, aprenderá los conceptos básicos
para incluir su parche en el árbol del kernel de Linux, y posiblemente
descubrir en la dirección en que trabajar a continuación, si no tiene ya
una idea.
Antes de realizar cualquier modificación real al código del kernel de
Linux, es imperativo entender cómo funciona el código en cuestión. Para
este propósito, nada es mejor que leerlo directamente (lo más complicado
está bien comentado), tal vez incluso con la ayuda de herramientas
especializadas. Una de esas herramientas que se recomienda especialmente
es el proyecto Linux Cross-Reference, que es capaz de presentar el código
fuente en un formato de página web indexada y autorreferencial. Una
excelente puesta al día del repositorio del código del kernel se puede
encontrar en:
https://elixir.bootlin.com/
El proceso de desarrollo
------------------------
El proceso de desarrollo del kernel de Linux consiste actualmente de
diferentes "branches" (ramas) con muchos distintos subsistemas específicos
a cada una de ellas. Las diferentes ramas son:
- El código principal de Linus (mainline tree)
- Varios árboles estables con múltiples major numbers
- Subsistemas específicos
- linux-next, para integración y testing
Mainline tree (Árbol principal)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
El mainline tree es mantenido por Linus Torvalds, y puede encontrarse en
https://kernel.org o en su repo. El proceso de desarrollo es el siguiente:
- Tan pronto como se lanza un nuevo kernel, se abre una ventana de dos
semanas, durante este período de tiempo, los maintainers pueden enviar
grandes modificaciones a Linus, por lo general los parches que ya se
han incluido en el linux-next durante unas semanas. La forma preferida
de enviar grandes cambios es usando git (la herramienta de
administración de código fuente del kernel, más información al respecto
en https://git-scm.com/), pero los parches simples también son validos.
- Después de dos semanas, se lanza un kernel -rc1 y la atención se centra
en hacer el kernel nuevo lo más estable ("solido") posible. La mayoría
de los parches en este punto deben arreglar una regresión. Los errores
que siempre han existido no son regresiones, por lo tanto, solo envíe
este tipo de correcciones si son importantes. Tenga en cuenta que se
podría aceptar un controlador (o sistema de archivos) completamente
nuevo después de -rc1 porque no hay riesgo de causar regresiones con
tal cambio, siempre y cuando el cambio sea autónomo y no afecte áreas
fuera del código que se está agregando. git se puede usar para enviar
parches a Linus después de que se lance -rc1, pero los parches también
deben ser enviado a una lista de correo pública para su revisión.
- Se lanza un nuevo -rc cada vez que Linus considera que el árbol git
actual esta en un estado razonablemente sano y adecuado para la prueba.
La meta es lanzar un nuevo kernel -rc cada semana.
- El proceso continúa hasta que el kernel se considera "listo", y esto
puede durar alrededor de 6 semanas.
Vale la pena mencionar lo que Andrew Morton escribió en las listas de
correo del kernel de Linux, sobre lanzamientos del kernel (traducido):
*"Nadie sabe cuándo se publicara un nuevo kernel, pues esto sucede
según el estado de los bugs, no de una cronología preconcebida."*
Varios árboles estables con múltiples major numbers
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Los kernels con versiones de 3 partes son kernels estables. Estos contienen
correcciones relativamente pequeñas y críticas para problemas de seguridad
o importantes regresiones descubiertas para una publicación de código.
Cada lanzamiento en una gran serie estable incrementa la tercera parte de
la versión número, manteniendo las dos primeras partes iguales.
Esta es la rama recomendada para los usuarios que quieren la versión
estable más reciente del kernel, y no están interesados en ayudar a probar
versiones en desarrollo/experimentales.
Los árboles estables son mantenidos por el equipo "estable"
<stable@vger.kernel.org>, y se liberan (publican) según lo dicten las
necesidades. El período de liberación normal es de aproximadamente dos
semanas, pero puede ser más largo si no hay problemas apremiantes. Un
problema relacionado con la seguridad, en cambio, puede causar un
lanzamiento casi instantáneamente.
El archivo :ref:`Documentación/proceso/stable-kernel-rules.rst <stable_kernel_rules>`
en el árbol del kernel documenta qué tipos de cambios son aceptables para
el árbol estable y cómo funciona el proceso de lanzamiento.
Subsistemas específicos
~~~~~~~~~~~~~~~~~~~~~~~~
Los maintainers de los diversos subsistemas del kernel --- y también muchos
desarrolladores de subsistemas del kernel --- exponen su estado actual de
desarrollo en repositorios fuente. De esta manera, otros pueden ver lo que
está sucediendo en las diferentes áreas del kernel. En áreas donde el
desarrollo es rápido, se le puede pedir a un desarrollador que base sus
envíos en tal árbol del subsistema del kernel, para evitar conflictos entre
este y otros trabajos ya en curso.
La mayoría de estos repositorios son árboles git, pero también hay otros
SCM en uso, o colas de parches que se publican como series quilt. Las
direcciones de estos repositorios de subsistemas se enumeran en el archivo
MAINTAINERS. Muchos de estos se pueden ver en https://git.kernel.org/.
Antes de que un parche propuesto se incluya con dicho árbol de subsistemas,
es sujeto a revisión, que ocurre principalmente en las listas de correo
(ver la sección respectiva a continuación). Para varios subsistemas del
kernel, esta revisión se rastrea con la herramienta patchwork. Patchwork
ofrece una interfaz web que muestra publicaciones de parches, cualquier
comentario sobre un parche o revisiones a él, y los maintainers pueden
marcar los parches como en revisión, aceptado, o rechazado. La mayoría de
estos sitios de trabajo de parches se enumeran en
https://patchwork.kernel.org/.
linux-next, para integración y testing
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Antes de que las actualizaciones de los árboles de subsistemas se combinen
con el árbol principal, necesitan probar su integración. Para ello, existe
un repositorio especial de pruebas en el que se encuentran casi todos los
árboles de subsistema, actualizado casi a diario:
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
De esta manera, linux-next ofrece una perspectiva resumida de lo que se
espera que entre en el kernel principal en el próximo período de "merge"
(fusión de código). Los testers aventureros son bienvenidos a probar
linux-next en ejecución.
Reportar bugs
-------------
El archivo 'Documentación/admin-guide/reporting-issues.rst' en el
directorio principal del kernel describe cómo informar un posible bug del
kernel y detalles sobre qué tipo de información necesitan los
desarrolladores del kernel para ayudar a rastrear la fuente del problema.
Gestión de informes de bugs
------------------------------
Una de las mejores formas de poner en práctica sus habilidades de hacking
es arreglando errores reportados por otras personas. No solo ayudará a
hacer el kernel más estable, también aprenderá a solucionar problemas del
mundo real y mejora sus habilidades, y otros desarrolladores se darán
cuenta de tu presencia. La corrección de errores es una de las mejores
formas de ganar méritos entre desarrolladores, porque no a muchas personas
les gusta perder el tiempo arreglando los errores de otras personas.
Para trabajar en informes de errores ya reportados, busque un subsistema
que le interese. Verifique el archivo MAINTAINERS donde se informan los
errores de ese subsistema; con frecuencia será una lista de correo, rara
vez un rastreador de errores (bugtracker). Busque en los archivos de dicho
lugar para informes recientes y ayude donde lo crea conveniente. También es
posible que desee revisar https://bugzilla.kernel.org para informes de
errores; solo un puñado de subsistemas del kernel lo emplean activamente
para informar o rastrear; sin embargo, todos los errores para todo el kernel
se archivan allí.
Listas de correo
-----------------
Como se explica en algunos de los documentos anteriores, la mayoría de
desarrolladores del kernel participan en la lista de correo del kernel de
Linux. Detalles sobre cómo para suscribirse y darse de baja de la lista se
pueden encontrar en:
https://subspace.kernel.org/subscribing.html
Existen archivos de la lista de correo en la web en muchos lugares
distintos. Utilice un motor de búsqueda para encontrar estos archivos. Por
ejemplo:
https://lore.kernel.org/linux-kernel/
Es muy recomendable que busque en los archivos sobre el tema que desea
tratar, antes de publicarlo en la lista. Un montón de cosas ya discutidas
en detalle solo se registran en los archivos de la lista de correo.
La mayoría de los subsistemas individuales del kernel también tienen sus
propias lista de correo donde hacen sus esfuerzos de desarrollo. Revise el
archivo MAINTAINERS para obtener referencias de lo que estas listas para
los diferentes grupos.
Muchas de las listas están alojadas en kernel.org. La información sobre
estas puede ser encontrada en:
https://subspace.kernel.org
Recuerde mantener buenos hábitos de comportamiento al usar las listas.
Aunque un poco cursi, la siguiente URL tiene algunas pautas simples para
interactuar con la lista (o cualquier lista):
https://subspace.kernel.org/etiquette.html
Si varias personas responden a su correo, el CC (lista de destinatarios)
puede hacerse bastante grande. No elimine a nadie de la lista CC: sin una
buena razón, o no responda solo a la dirección de la lista. Acostúmbrese
a recibir correos dos veces, una del remitente y otra de la lista, y no
intente ajustar esto agregando encabezados de correo astutos, a la gente no
le gustará.
Recuerde mantener intacto el contexto y la atribución de sus respuestas,
mantenga las líneas "El hacker John Kernel escribió ...:" en la parte
superior de su respuesta, y agregue sus declaraciones entre las secciones
individuales citadas en lugar de escribiendo en la parte superior del
correo electrónico.
Si incluye parches en su correo, asegúrese de que sean texto legible sin
formato como se indica en :ref:`Documentation/process/submitting-patches.rst <submittingpatches>`.
Los desarrolladores del kernel no quieren lidiar con archivos adjuntos o
parches comprimidos; y pueden querer comentar líneas individuales de su
parche, que funciona sólo de esa manera. Asegúrese de emplear un programa
de correo que no altere los espacios ni los tabuladores. Una buena primera
prueba es enviarse el correo a usted mismo, e intentar aplicar su
propio parche. Si eso no funciona, arregle su programa de correo o
reemplace hasta que funcione.
Sobretodo, recuerde de ser respetuoso con otros subscriptores.
Colaborando con la comunidad
----------------------------
El objetivo de la comunidad del kernel es proporcionar el mejor kernel
posible. Cuando envíe un parche para su aceptación, se revisará en sus
méritos técnicos solamente. Entonces, ¿qué deberías ser?
- críticas
- comentarios
- peticiones de cambios
- peticiones de justificaciones
- silencio
Recuerde, esto es parte de introducir su parche en el kernel. Tiene que ser
capaz de recibir críticas y comentarios sobre sus parches, evaluar
a nivel técnico y re-elaborar sus parches o proporcionar razonamiento claro
y conciso de por qué no se deben hacer tales cambios. Si no hay respuestas
a su publicación, espere unos días e intente de nuevo, a veces las cosas se
pierden dado el gran volumen.
¿Qué no debería hacer?
- esperar que su parche se acepte sin preguntas
- actuar de forma defensiva
- ignorar comentarios
- enviar el parche de nuevo, sin haber aplicados los cambios pertinentes
En una comunidad que busca la mejor solución técnica posible, siempre habrá
diferentes opiniones sobre lo beneficioso que es un parche. Tiene que ser
cooperativo y estar dispuesto a adaptar su idea para que encaje dentro
del kernel, o al menos esté dispuesto a demostrar que su idea vale la pena.
Recuerde, estar equivocado es aceptable siempre y cuando estés dispuesto a
trabajar hacia una solución que sea correcta.
Es normal que las respuestas a su primer parche sean simplemente una lista
de una docena de cosas que debe corregir. Esto **no** implica que su
parche no será aceptado, y **no** es personal. Simplemente corrija todos
los problemas planteados en su parche, y envié otra vez.
Diferencias entre la comunidad kernel y las estructuras corporativas
--------------------------------------------------------------------
La comunidad del kernel funciona de manera diferente a la mayoría de los
entornos de desarrollo tradicionales en empresas. Aquí hay una lista de
cosas que puede intentar hacer para evitar problemas:
Cosas buenas que decir respecto a los cambios propuestos:
- "Esto arregla múltiples problemas."
- "Esto elimina 2000 lineas de código."
- "Aquí hay un parche que explica lo que intento describir."
- "Lo he testeado en 5 arquitecturas distintas..."
- "Aquí hay una serie de parches menores que..."
- "Esto mejora el rendimiento en maquinas típicas..."
Cosas negativas que debe evitar decir:
- "Lo hicimos así en AIX/ptx/Solaris, de modo que debe ser bueno..."
- "Llevo haciendo esto 20 años, de modo que..."
- "Esto lo necesita mi empresa para ganar dinero"
- "Esto es para la linea de nuestros productos Enterprise"
- "Aquí esta el documento de 1000 paginas describiendo mi idea"
- "Llevo 6 meses trabajando en esto..."
- "Aquí esta un parche de 5000 lineas que..."
- "He rescrito todo el desastre actual, y aquí esta..."
- "Tengo un deadline, y este parche debe aplicarse ahora."
Otra forma en que la comunidad del kernel es diferente a la mayoría de los
entornos de trabajo tradicionales en ingeniería de software, es la
naturaleza sin rostro de interacción. Una de las ventajas de utilizar el
correo electrónico y el IRC como formas principales de comunicación es la
no discriminación por motivos de género o raza. El entorno de trabajo del
kernel de Linux acepta a mujeres y minorías porque todo lo que eres es una
dirección de correo electrónico. El aspecto internacional también ayuda a
nivelar el campo de juego porque no puede adivinar el género basado en
el nombre de una persona. Un hombre puede llamarse Andrea y una mujer puede
llamarse Pat. La mayoría de las mujeres que han trabajado en el kernel de
Linux y han expresado una opinión han tenido experiencias positivas.
La barrera del idioma puede causar problemas a algunas personas que no se
sientes cómodas con el inglés. Un buen dominio del idioma puede ser
necesario para transmitir ideas correctamente en las listas de correo, por
lo que le recomendamos que revise sus correos electrónicos para asegurarse
de que tengan sentido en inglés antes de enviarlos.
Divida sus cambios
---------------------
La comunidad del kernel de Linux no acepta con gusto grandes fragmentos de
código, sobretodo a la vez. Los cambios deben introducirse correctamente,
discutidos y divididos en pequeñas porciones individuales. Esto es casi
exactamente lo contrario de lo que las empresas están acostumbradas a hacer.
Su propuesta también debe introducirse muy temprano en el proceso de
desarrollo, de modo que pueda recibir comentarios sobre lo que está
haciendo. También deje que la comunidad sienta que está trabajando con
ellos, y no simplemente usándolos como un vertedero para su función. Sin
embargo, no envíe 50 correos electrónicos a una vez a una lista de correo,
su serie de parches debe casi siempre ser más pequeña que eso.
Las razones para dividir las cosas son las siguientes:
1) Los cambios pequeños aumentan la probabilidad de que sus parches sean
aplicados, ya que no requieren mucho tiempo o esfuerzo para verificar su
exactitud. Un parche de 5 líneas puede ser aplicado por un maintainer
con apenas una segunda mirada. Sin embargo, un parche de 500 líneas
puede tardar horas en ser revisado en términos de corrección (el tiempo
que toma es exponencialmente proporcional al tamaño del parche, o algo
así).
Los parches pequeños también facilitan la depuración cuando algo falla.
Es mucho más fácil retirar los parches uno por uno que diseccionar un
parche muy grande después de haber sido aplicado (y roto alguna cosa).
2) Es importante no solo enviar pequeños parches, sino también reescribir
y simplificar (o simplemente reordenar) los parches antes de enviarlos.
Esta es una analogía del desarrollador del kernel Al Viro (traducida):
*"Piense en un maestro que califica la tarea de un estudiante de
matemáticas. El maestro no quiere ver los intentos y errores del
estudiante antes de que se les ocurriera la solución. Quiere ver la
respuesta más limpia y elegante. Un buen estudiante lo sabe, y nunca
presentaría su trabajo intermedio antes de tener la solución final.*
*Lo mismo ocurre con el desarrollo del kernel. Los maintainers y
revisores no quieren ver el proceso de pensamiento detrás de la solución
al problema que se está resolviendo. Quieren ver un solución simple y
elegante."*
Puede resultar un reto mantener el equilibrio entre presentar una solución
elegante y trabajar junto a la comunidad, discutiendo su trabajo inacabado.
Por lo tanto, es bueno comenzar temprano en el proceso para obtener
"feedback" y mejorar su trabajo, pero también mantenga sus cambios en
pequeños trozos que pueden ser aceptados, incluso cuando toda su labor no
está listo para inclusión en un momento dado.
También tenga en cuenta que no es aceptable enviar parches para su
inclusión que están sin terminar y serán "arreglados más tarde".
Justifique sus cambios
----------------------
Además de dividir sus parches, es muy importante que deje a la comunidad de
Linux sabe por qué deberían agregar este cambio. Nuevas características
debe justificarse como necesarias y útiles.
Documente sus cambios
---------------------
Cuando envíe sus parches, preste especial atención a lo que dice en el
texto de su correo electrónico. Esta información se convertirá en el
ChangeLog del parche, y se conservará para que todos la vean, todo el
tiempo. Debe describir el parche por completo y contener:
- por qué los cambios son necesarios
- el diseño general de su propuesta
- detalles de implementación
- resultados de sus experimentos
Para obtener más detalles sobre cómo debería quedar todo esto, consulte la
sección ChangeLog del documento:
"The Perfect Patch"
https://www.ozlabs.org/~akpm/stuff/tpp.txt
Todas estas cuestiones son a veces son muy difíciles de conseguir. Puede
llevar años perfeccionar estas prácticas (si es que lo hace). Es un proceso
continuo de mejora que requiere mucha paciencia y determinación. Pero no se
rinda, es posible. Muchos lo han hecho antes, y cada uno tuvo que comenzar
exactamente donde está usted ahora.
----------
Gracias a Paolo Ciarrocchi que permitió que la sección "Development Process"
se basara en el texto que había escrito (https://lwn.net/Articles/94386/),
y a Randy Dunlap y Gerrit Huizenga por algunas de la lista de cosas que
debes y no debes decir. También gracias a Pat Mochel, Hanna Linder, Randy
Dunlap, Kay Sievers, Vojtech Pavlik, Jan Kara, Josh Boyer, Kees Cook,
Andrew Morton, Andi Kleen, Vadim Lobanov, Jesper Juhl, Adrian Bunk,
Keri Harris, Frans Pop, David A. Wheeler, Junio Hamano, Michael Kerrisk y
Alex Shepard por su revisión, comentarios y contribuciones. Sin su ayuda,
este documento no hubiera sido posible.
Maintainer: Greg Kroah-Hartman <greg@kroah.com>
@@ -0,0 +1,32 @@
.. raw:: latex
\renewcommand\thesection*
\renewcommand\thesubsection*
.. include:: ../disclaimer-sp.rst
.. _sp_process_index:
.. toctree::
:maxdepth: 1
development-process
submitting-patches
kernel-docs
coding-style
code-of-conduct
kernel-enforcement-statement
email-clients
magic-number
programming-language
deprecated
adding-syscalls
researcher-guidelines
contribution-maturity-model
security-bugs
embargoed-hardware-issues
handling-regressions
management-style
submit-checklist
howto
maintainer-kvm-x86
@@ -0,0 +1,186 @@
.. include:: ../disclaimer-sp.rst
:Original: :ref:`Documentation/process/kernel-docs.rst <kernel_docs>`
:Translator: Carlos Bilbao <carlos.bilbao.osdev@gmail.com>
.. _sp_kernel_docs:
Índice de documentación adicional del kernel
============================================
La necesidad de un documento como este se hizo evidente en la lista de
correo de linux-kernel cuando las mismas preguntas, solicitando sugerencias
e información, aparecieron una y otra vez.
Afortunadamente, a medida que más y más gente accede a GNU/Linux, más
desarrolladores se interesan por el kernel. Sin embargo, leer las fuentes
no siempre es suficiente. Es fácil entender el código, pero se pierden los
conceptos, la filosofía y decisiones de diseño detrás de dicho código.
Desafortunadamente, no existen muchos documentos disponibles para que los
principiantes comiencen. Y, aunque existieran, no habría ningún lugar
"conocido" que les pudiera seguir la pista. Estas líneas tratan de cubrir
esta carencia.
POR FAVOR, si conoce algún documento que no figura aquí, o si escribe un
nuevo documento, incluya una referencia aquí, siguiendo el proceso de envío
de parches del kernel. Cualquier corrección, idea o comentario también es
bienvenida.
Todos los documentos se catalogan con los siguientes campos: el "Título",
el "Autor"/es, la "URL" donde se encuentran, algunas "Palabras clave"
útiles para buscar temas específicos, y una breve "Descripción" del
documento en cuestión.
.. note::
Los documentos de cada sección en este documento están ordenados por su
fecha de publicación, del más reciente al más antiguo. Los maintainers
deben ir retirando recursos obsoletos o anticuados.
Documentos en el árbol del kernel Linux
-----------------------------------------
Los libros de Sphinx deben compilarse con ``make {htmldocs | pdfdocs | epubdocs}``.
* Título: **linux/Documentation**
:Autor: Many.
:Ubicación: Documentation/
:Palabras Clave: archivos de texto, Sphinx.
:Descripción: Documentación que viene con las fuentes del kernel,
dentro del directorio Documentation. Algunas páginas de este documento
(incluido este documento en sí) se han trasladado allí, y podrían
estar más actualizadas que la versión web.
Documentos en línea
-------------------
* Título: **Linux Kernel Mailing List Glossary**
:Autor: various
:URL: https://kernelnewbies.org/KernelGlossary
:Fecha: rolling version
:Palabras Clave: glosario terminos, linux-kernel.
:Descripción: De la Introducción: "This glossary is intended as
a brief description of some of the acronyms and terms you may hear
during discussion of the Linux kernel".
* Título: **The Linux Kernel Module Programming Guide**
:Autor: Peter Jay Salzman, Michael Burian, Ori Pomerantz, Bob Mottram,
Jim Huang.
:URL: https://sysprog21.github.io/lkmpg/
:Fecha: 2021
:Palabras Clave: modules, GPL book, /proc, ioctls, system calls,
interrupt handlers, llamadas al sistema, interrupciones.
:Descripción: Un muy buen libro GPL sobre el tema de la programación
de módulos. Muchos ejemplos. Actualmente la nueva versión está
siendo mantenida activamente ent https://github.com/sysprog21/lkmpg.
Libros publicados
-----------------
* Título: **Linux Kernel Programming: A Comprehensive Guide to Kernel Internals, Writing Kernel Modules, and Kernel Synchronization**
:Autor: Kaiwan N. Billimoria
:Publica: Packt Publishing Ltd
:Fecha: 2021
:Paginas: 754
:ISBN: 978-1789953435
* Título: **Linux Kernel Development, 3rd Edition**
:Autor: Robert Love
:Publica: Addison-Wesley
:Fecha: July, 2010
:Paginas: 440
:ISBN: 978-0672329463
:Notas: Libro fundacional
.. _sp_ldd3_published:
* Título: **Linux Device Drivers, 3rd Edition**
:Authors: Jonathan Corbet, Alessandro Rubini, and Greg Kroah-Hartman
:Publica: O'Reilly & Associates
:Fecha: 2005
:Paginas: 636
:ISBN: 0-596-00590-3
:Notas: Libro fundacional. Más información en
http://www.oreilly.com/catalog/linuxdrive3/
formato PDF, URL: https://lwn.net/Kernel/LDD3/
* Título: **The Design of the UNIX Operating System**
:Autor: Maurice J. Bach
:Publica: Prentice Hall
:Fecha: 1986
:Paginas: 471
:ISBN: 0-13-201757-1
:Notas: Libro fundacional
Recursos varios
---------------
* Título: **Cross-Referencing Linux**
:URL: https://elixir.bootlin.com/
:Palabras Clave: Browsing source code.
:Descripción: Otro navegador de código fuente del kernel Linux que se
encuentra en la web. Muchas referencias cruzadas a variables y
funciones. Puedes ver dónde se definen y dónde se utilizan.
* Título: **Linux Weekly News**
:URL: https://lwn.net
:Palabras Clave: latest kernel news, noticias del kernel Linux.
:Descripción: El título lo dice todo (Noticias Semanales de Linux).
Hay una sección fija sobre el kernel, resumiendo el trabajo de sus
desarrolladores, correcciones de errores, nuevas funciones y
versiones, producido durante la semana.
* Título: **The home page of Linux-MM**
:Autor: The Linux-MM team.
:URL: https://linux-mm.org/
:Palabras Clave: memory management, Linux-MM, mm patches, TODO, docs,
mailing list, administración de memoria, Linux-MM, parches mm, listas
de correo.
:Descripción: Sitio dedicado al desarrollo de la gestión de memoria
de Linux. Parches relacionados con la memoria, HOWTOs, enlaces,
desarrolladores de mm... ¡Si está interesado en el desarrollo de la
gestión de memoria no te lo pierdas!
* Título: **Kernel Newbies IRC Channel and Website**
:URL: https://www.kernelnewbies.org
:Palabras Clave: IRC, newbies, channel, asking doubts, canal, dudas,
novatos, preguntar.
:Descripción: #kernelnewbies en irc.oftc.net.
#kernelnewbies es una red de IRC dedicada al hacker del kernel
'novato'. La audiencia se compone principalmente de personas que
quieren aprender sobre el kernel, trabajar en proyectos del kernel
o hackers profesionales del kernel que quieren ayudar a la gente
menos experimentada.
#kernelnewbies es parte de la red OFTC IRC.
Pruebe con irc.oftc.net como su servidor y luego haga /join
#kernelnewbies.
El sitio web kernelnewbies también alberga artículos, documentos, FAQs...
* Título: **linux-kernel mailing list archives and search engines**
:URL: https://subspace.kernel.org
:URL: https://lore.kernel.org
:Palabras Clave: linux-kernel, archives, buscar, search, archivos.
:Descripción: Algunos de los archivadores de listas de correo del
kernel de Linux. Si usted tiene uno mejor/otro, por favor hágamelo
saber.
-------
Este documento se basaba originalmente en:
https://www.dit.upm.es/~jmseyas/linux/kernel/hackers-docs.html
escrito por Juan-Mariano de Goyenche
@@ -0,0 +1,174 @@
.. include:: ../disclaimer-sp.rst
:Original: :ref:`Documentation/process/kernel-enforcement-statement.rst <process_statement_kernel>`
:Translator: Carlos Bilbao <carlos.bilbao.osdev@gmail.com>
.. _sp_process_statement_kernel:
Aplicación de la licencia en el kernel Linux
============================================
Como desarrolladores del kernel Linux, tenemos un gran interés en cómo se
se utiliza nuestro software y cómo se aplica la licencia de nuestro software.
El cumplimiento de las obligaciones de intercambio recíproco de GPL-2.0 son
fundamentales en el largo plazo para la sostenibilidad de nuestro software
y comunidad.
Aunque existe el derecho de hacer valer un copyright distinto en las
contribuciones hechas a nuestra comunidad, compartimos el interés de
asegurar que las acciones individuales para proteger estos se lleven a cabo
de una manera que beneficia a nuestra comunidad y no tenga un indeseado
impacto negativo en la salud y crecimiento de nuestro ecosistema de software.
Con el fin de disuadir la aplicación inútil de acciones, estamos de acuerdo
en que es en el mejor interés de nuestro desarrollo como comunidad asumir
el siguiente compromiso con los usuarios del kernel Linux, en nombre
nuestro y de cualquier sucesor de nuestros derechos de autor (copyright):
Sin perjuicio de las disposiciones de terminación de GPL-2.0, aceptamos
que es en el mejor interés de nuestra comunidad de desarrollo adoptar
las siguientes disposiciones de GPL-3.0 como permisos adicionales bajo
nuestra licencia, con respecto a cualquier interposición de alegación
de infringimiento (en inglés, "non-defensive assertion") de los
derechos bajo la licencia.
Sin embargo, si deja de violar esta Licencia, entonces su licencia
de copyright como particular se restablece (a) provisionalmente,
a menos que y hasta que el titular de los derechos de autor explícita
y finalmente rescinda su licencia, y (b) de forma permanente, si el
titular de los derechos de autor no le notifica la violación por algún
medio razonable antes de 60 días después del cese.
Además, su licencia de un titular de derechos de autor en particular es
restablecida permanentemente si el titular de los derechos de autor le
notifica de la violación por algún medio razonable, esta es la primera
vez que ha recibido notificación de violación de esta Licencia (para
cualquier trabajo) de ese titular de los derechos de autor, y subsana
la infracción antes de los 30 días posteriores de recibir el aviso.
Nuestra intención al proporcionar estas garantías es fomentar un mayor uso
del software. Queremos que empresas y particulares utilicen, modifiquen y
distribuyan este software. Queremos trabajar con los usuarios de forma
abierta y transparente para eliminar cualquier incertidumbre sobre nuestras
expectativas con respecto al cumplimiento que podría limitar la adopción de
nuestro software. Entendemos la acción legal como último recurso, que se
iniciará solo cuando otros esfuerzos de la comunidad no hayan podido
resolver el problema.
Finalmente, una vez que se resuelva un problema de incumplimiento,
esperamos que el usuario se sienta bienvenido a unirse a nosotros en
nuestros esfuerzos con este proyecto. Trabajando juntos, somos más fuertes.
Excepto donde se indica a continuación, hablamos solo por nosotros mismos y
no por ninguna compañía donde puede que trabajemos hoy, o hayamos trabajado
en el pasado, o trabajaremos en el futuro.
- Laura Abbott
- Bjorn Andersson (Linaro)
- Andrea Arcangeli
- Neil Armstrong
- Jens Axboe
- Pablo Neira Ayuso
- Khalid Aziz
- Ralf Baechle
- Felipe Balbi
- Arnd Bergmann
- Ard Biesheuvel
- Tim Bird
- Paolo Bonzini
- Christian Borntraeger
- Mark Brown (Linaro)
- Paul Burton
- Javier Martinez Canillas
- Rob Clark
- Kees Cook (Google)
- Jonathan Corbet
- Dennis Dalessandro
- Vivien Didelot (Savoir-faire Linux)
- Hans de Goede
- Mel Gorman (SUSE)
- Sven Eckelmann
- Alex Elder (Linaro)
- Fabio Estevam
- Larry Finger
- Bhumika Goyal
- Andy Gross
- Juergen Gross
- Shawn Guo
- Ulf Hansson
- Stephen Hemminger (Microsoft)
- Tejun Heo
- Rob Herring
- Masami Hiramatsu
- Michal Hocko
- Simon Horman
- Johan Hovold (Hovold Consulting AB)
- Christophe JAILLET
- Olof Johansson
- Lee Jones (Linaro)
- Heiner Kallweit
- Srinivas Kandagatla
- Jan Kara
- Shuah Khan (Samsung)
- David Kershner
- Jaegeuk Kim
- Namhyung Kim
- Colin Ian King
- Jeff Kirsher
- Greg Kroah-Hartman (Linux Foundation)
- Christian König
- Vinod Koul
- Krzysztof Kozlowski
- Viresh Kumar
- Aneesh Kumar K.V
- Julia Lawall
- Doug Ledford
- Chuck Lever (Oracle)
- Daniel Lezcano
- Shaohua Li
- Xin Long
- Tony Luck
- Catalin Marinas (Arm Ltd)
- Mike Marshall
- Chris Mason
- Paul E. McKenney
- Arnaldo Carvalho de Melo
- David S. Miller
- Ingo Molnar
- Kuninori Morimoto
- Trond Myklebust
- Martin K. Petersen (Oracle)
- Borislav Petkov
- Jiri Pirko
- Josh Poimboeuf
- Sebastian Reichel (Collabora)
- Guenter Roeck
- Joerg Roedel
- Leon Romanovsky
- Steven Rostedt (VMware)
- Frank Rowand
- Ivan Safonov
- Anna Schumaker
- Jes Sorensen
- K.Y. Srinivasan
- David Sterba (SUSE)
- Heiko Stuebner
- Jiri Kosina (SUSE)
- Willy Tarreau
- Dmitry Torokhov
- Linus Torvalds
- Thierry Reding
- Rik van Riel
- Luis R. Rodriguez
- Geert Uytterhoeven (Glider bvba)
- Eduardo Valentin (Amazon.com)
- Daniel Vetter
- Linus Walleij
- Richard Weinberger
- Dan Williams
- Rafael J. Wysocki
- Arvind Yadav
- Masahiro Yamada
- Wei Yongjun
- Lv Zheng
- Marc Zyngier (Arm Ltd)
@@ -0,0 +1,86 @@
.. include:: ../disclaimer-sp.rst
:Original: :ref:`Documentation/staging/magic-number.rst <magicnumbers>`
:Translator: Carlos Bilbao <carlos.bilbao.osdev@gmail.com>
.. _sp_magicnumbers:
Números mágicos de Linux
========================
Este archivo es un registro de los números mágicos que están en uso. Cuando
usted incluya un número mágico a una estructura, también debe agregarlo a
este documento, ya que es mejor si los números mágicos utilizados por
varias estructuras son únicos.
Es una muy buena idea proteger las estructuras de datos del kernel con
números mágicos. Esto le permite verificar en tiempo de ejecución si (a)
una estructura ha sido manipulada, o (b) ha pasado la estructura incorrecta
a una rutina. Esto último es especialmente útil --- particularmente cuando
pasa punteros a estructuras a través de un puntero void \*. El código tty,
por ejemplo, hace esto con frecuencia para pasar información específica del
driver y líneas de estructuras específicas de protocolo de un lado al
otro.
La forma de usar números mágicos es declararlos al principio de la
estructura, así::
struct tty_ldisc {
int magic;
...
};
Por favor, siga este método cuando agregue futuras mejoras al kernel! Me ha
ahorrado innumerables horas de depuración, especialmente en los casos
complicados donde una matriz ha sido invadida y las estructuras que siguen
a la matriz se han sobrescrito. Usando este método, estos casos se detectan
de forma rápida y segura.
Changelog::
Theodore Ts'o
31 Mar 94
La tabla mágica ha sido actualizada para Linux 2.1.55.
Michael Chastain
<mailto:mec@shout.net>
22 Sep 1997
Ahora debería estar actualizada con Linux 2.1.112. Porque
estamos en fase de "feature freeze", es muy poco probable que
algo cambiará antes de 2.2.x. Las entradas son
ordenados por campo numérico.
Krzysztof G. Baranowski
<mailto: kgb@knm.org.pl>
29 Jul 1998
Se actualizó la tabla mágica a Linux 2.5.45. Justo sobre el feature
freeze, pero es posible que algunos nuevos números mágicos se cuelen en
el kernel antes de 2.6.x todavía.
Petr Baudis
<pasky@ucw.cz>
03 Nov 2002
La tabla mágica ha sido actualizada para Linux 2.5.74.
Fabian Frederick
<ffrederick@users.sourceforge.net>
09 Jul 2003
===================== ================ ======================== ==========================================
Magic Name Number Structure File
===================== ================ ======================== ==========================================
PG_MAGIC 'P' pg_{read,write}_hdr ``include/linux/pg.h``
APM_BIOS_MAGIC 0x4101 apm_user ``arch/x86/kernel/apm_32.c``
FASYNC_MAGIC 0x4601 fasync_struct ``include/linux/fs.h``
SLIP_MAGIC 0x5302 slip ``drivers/net/slip.h``
KV_MAGIC 0x5f4b565f kernel_vars_s ``arch/mips/include/asm/sn/klkernvars.h``
CODA_MAGIC 0xC0DAC0DA coda_file_info ``fs/coda/coda_fs_i.h``
CCB_MAGIC 0xf2691ad2 ccb ``drivers/scsi/ncr53c8xx.c``
QUEUE_MAGIC_FREE 0xf7e1c9a3 queue_entry ``drivers/scsi/arm/queue.c``
QUEUE_MAGIC_USED 0xf7e1cc33 queue_entry ``drivers/scsi/arm/queue.c``
NMI_MAGIC 0x48414d4d455201 nmi_s ``arch/mips/include/asm/sn/nmi.h``
===================== ================ ======================== ==========================================
@@ -0,0 +1,465 @@
.. include:: ../disclaimer-sp.rst
:Original: Documentation/process/maintainer-kvm-x86.rst
:Translator: Juan Embid <jembid@ucm.es>
KVM x86
=======
Prólogo
--------
KVM se esfuerza por ser una comunidad acogedora; las contribuciones de los
recién llegados son valoradas e incentivadas. Por favor, no se desanime ni
se sienta intimidado por la extensión de este documento y las numerosas
normas/directrices que contiene. Todos cometemos errores y todos hemos sido
principiantes en algún momento. Mientras haga un esfuerzo honesto por
seguir las directrices de KVM x86, sea receptivo a los comentarios, y
aprenda de los errores que cometa, será recibido con los brazos abiertos,
no con antorchas y horcas.
TL;DR
-----
Las pruebas son obligatorias. Sea coherente con los estilos y patrones
establecidos.
Árboles
-------
KVM x86 se encuentra actualmente en un período de transición de ser parte
del árbol principal de KVM, a ser "sólo otra rama de KVM". Como tal, KVM
x86 está dividido entre el árbol principal de KVM,
``git.kernel.org/pub/scm/virt/kvm/kvm.git``, y un árbol específico de KVM
x86, ``github.com/kvm-x86/linux.git``.
Por lo general, las correcciones para el ciclo en curso se aplican
directamente al árbol principal de KVM, mientras que todo el desarrollo
para el siguiente ciclo se dirige a través del árbol de KVM x86. En el
improbable caso de que una corrección para el ciclo actual se dirija a
través del árbol KVM x86, se aplicará a la rama ``fixes`` antes de llegar
al árbol KVM principal.
Tenga en cuenta que se espera que este periodo de transición dure bastante
tiempo, es decir, que será el statu quo en un futuro previsible.
Ramas
~~~~~
El árbol de KVM x86 está organizado en múltiples ramas por temas. El
propósito de utilizar ramas temáticas más específicas es facilitar el
control de un área de desarrollo, y para limitar los daños colaterales de
errores humanos y/o commits con errores, por ejemplo, borrar el commit HEAD
de una rama temática no tiene impacto en los hashes SHA1 de otros commit
en en camino, y tener que rechazar una solicitud de pull debido a errores
retrasa sólo esa rama temática.
Todas las ramas temáticas, excepto ``next`` y ``fixes``, se agrupan en
``next`` a través de un Cthulhu merge en función de las necesidades, es
decir, cuando se actualiza una rama temática. Como resultado, los push
forzados a ``next`` son comunes.
Ciclo de Vida
~~~~~~~~~~~~~
Las correcciones dirigidas a la versión actual, también conocida como
mainline, suelen aplicarse directamente al árbol principal de KVM, es
decir, no pasan por el árbol x86 de KVM.
Los cambios dirigidos a la siguiente versión se dirigen a través del árbol
KVM x86. Se envían pull requests (de KVM x86 a KVM main) para cada rama
temática de KVM x86, normalmente la semana antes de que Linus abra la
ventana de fusión, por ejemplo, la semana siguiente a rc7 para las
versiones "normales". Si todo va bien, las ramas temáticas son subidas en
el pull request principal de KVM enviado durante la ventana de fusión de
Linus.
El árbol de KVM x86 no tiene su propia ventana de fusión oficial, pero hay
un cierre suave alrededor de rc5 para nuevas características, y un cierre
suave alrededor de rc6 para correcciones (para la próxima versión; fíjese
más arriba para las correcciones dirigidas a la versión actual).
Cronología
~~~~~~~~~~
Normalmente, los envíos se revisan y aplican en orden FIFO, con cierto
margen de maniobra en función del tamaño de la serie, los parches que están
"calientes en caché", etc. Correcciones, especialmente para la versión
actual y/o árboles estables, consiguen saltar la cola. Los parches que se
lleven a través de un árbol que no sea KVM (la mayoría de las veces a
través del árbol de consejos) y/o que tengan otros acks/revisiones también
saltan la cola hasta cierto punto.
Tenga en cuenta que la mayor parte de la revisión se realiza entre rc1 y
rc6, más o menos. El periodo entre la rc6 y la siguiente rc1 se utiliza
para ponerse al día en otras tareas, es decir, la falta de envíos durante
este periodo no es inusual.
Los pings para obtener una actualización del estado son bienvenidos, pero
tenga en cuenta el calendario del ciclo de publicación actual y tenga
expectativas realistas. Si está haciendo ping para la aceptación, es decir,
no sólo para obtener comentarios o una actualización, por favor haga todo
lo posible, dentro de lo razonable, para asegurarse de que sus parches
están listos para ser fusionados. Los pings sobre series que rompen la
compilación o fallan en las pruebas provocan el descontento de los
mantenedores.
Desarrollo
-----------
Árbol base/Rama
~~~~~~~~~~~~~~~
Las correcciones dirigidas a la versión actual, también conocida como
mainline, deben basarse en
``git://git.kernel.org/pub/scm/virt/kvm/kvm.git master``. Tenga en cuenta
que las correcciones no garantizan automáticamente la inclusión en la
versión actual. No hay una regla única, pero normalmente sólo las
correcciones de errores urgentes, críticos y/o introducidos en la versión
actual deberían incluirse en la versión actual.
Todo lo demás debería basarse en ``kvm-x86/next``, es decir, no hay
necesidad de seleccionar una rama temática específica como base. Si hay
conflictos y/o dependencias entre ramas, es trabajo del mantenedor
resolverlos.
La única excepción al uso de ``kvm-x86/next`` como base es si un
parche/serie es una serie multi-arquitectura, es decir, tiene
modificaciones no triviales en el código común de KVM y/o tiene cambios más
que superficiales en el código de otras arquitecturas. Los parches/series
multi-arquitectura deberían basarse en un punto común y estable en la
historia de KVM, por ejemplo, la versión candidata en la que se basa
``kvm-x86 next``. Si no está seguro de si un parche/serie es realmente
multiarquitectura, sea precavido y trátelo como multiarquitectura, es
decir, utilice una base común.
Estilo del codigo
~~~~~~~~~~~~~~~~~~~~~~
Cuando se trata de estilo, nomenclatura, patrones, etc., la coherencia es
la prioridad número uno en KVM x86. Si todo lo demás falla, haga coincidir
lo que ya existe.
Con algunas advertencias que se enumeran a continuación, siga las
recomendaciones de los responsables del árbol de consejos
:ref:`maintainer-tip-coding-style`, ya que los parches/series a menudo
tocan tanto archivos x86 KVM como no KVM, es decir, llaman la atención de
los mantenedores de KVM *y* del árbol de consejos.
El uso del abeto inverso, también conocido como árbol de Navidad inverso o
árbol XMAS inverso, para las declaraciones de variables no es estrictamente
necesario, aunque es preferible.
Excepto para unos pocos apuntes especiales, no utilice comentarios
kernel-doc para las funciones. La gran mayoría de las funciones "públicas"
de KVM no son realmente públicas, ya que están destinadas únicamente al
consumo interno de KVM (hay planes para privatizar las cabeceras y
exportaciones de KVM para reforzar esto).
Comentarios
~~~~~~~~~~~
Escriba los comentarios en modo imperativo y evite los pronombres. Utilice
los comentarios para ofrecer una visión general de alto nivel del código
y/o para explicar por qué el código hace lo que hace. No reitere lo que el
código hace literalmente; deje que el código hable por sí mismo. Si el
propio código es inescrutable, los comentarios no servirán de nada.
Referencias SDM y APM
~~~~~~~~~~~~~~~~~~~~~~
Gran parte de la base de código de KVM está directamente vinculada al
comportamiento de la arquitectura definido en El Manual de Desarrollo de
Software (SDM) de Intel y el Manual del Programador de Arquitectura (APM)
de AMD. El uso de "SDM de Intel" y "APM de AMD", o incluso sólo "SDM" o
"APM", sin contexto adicional es correcto.
No haga referencia a secciones específicas, tablas, figuras, etc. por su
número, especialmente en los comentarios. En su lugar, si es necesario
(véase más abajo), copie y pegue el fragmento correspondiente y haga
referencia a las secciones/tablas/figuras por su nombre. Los diseños del
SDM y el APM cambian constantemente, por lo que los números/etiquetas no
son estables.
En general, no haga referencia explícita ni copie-pegue del SDM o APM en
los comentarios. Con pocas excepciones, KVM *debe* respetar el
comportamiento de la arquitectura, por lo que está implícito que el
comportamiento de KVM está emulando el comportamiento de SDM y/o APM. Tenga
en cuenta que hacer referencia al SDM/APM en los registros de cambios para
justificar el cambio y proporcionar contexto es perfectamente correcto y
recomendable.
Shortlog
~~~~~~~~
El formato de prefijo más recomendable es ``KVM: <topic>:``, donde
``<topic>`` es uno de los siguientes::
- x86
- x86/mmu
- x86/pmu
- x86/xen
- autocomprobaciones
- SVM
- nSVM
- VMX
- nVMX
**¡NO use x86/kvm!** ``x86/kvm`` se usa exclusivamente para cambios de
Linux virtualizado por KVM, es decir, para arch/x86/kernel/kvm.c. No use
nombres de archivos o archivos completos como prefijo de asunto/shortlog.
Tenga en cuenta que esto no coincide con las ramas temáticas (las ramas
temáticas se preocupan mucho más por los conflictos de código).
Todos los nombres distinguen entre mayúsculas y minúsculas. ``KVM: x86:``
es correcto, ``kvm: vmx:`` no lo es.
Escriba en mayúsculas la primera palabra de la descripción condensada del
parche, pero omita la puntuación final. Por ejemplo::
KVM: x86: Corregir una desviación de puntero nulo en function_xyz()
no::
kvm: x86: corregir una desviación de puntero nulo en function_xyz.
Si un parche afecta a varios temas, recorra el árbol conceptual hasta
encontrar el primer padre común (que suele ser simplemente ``x86``). En
caso de duda, ``git log path/to/file`` debería proporcionar una pista
razonable.
De vez en cuando surgen nuevos temas, pero le rogamos que inicie un debate
en la lista si desea proponer la introducción de un nuevo tema, es decir,
no se ande con rodeos.
Consulte :ref:`the_canonical_patch_format` para obtener más información,
con una enmienda: no trate el límite de 70-75 caracteres como un límite
absoluto y duro. En su lugar, utilice 75 caracteres como límite firme, pero
no duro, y 80 caracteres como límite duro. Es decir, deje que el registro
corto sobrepase en algunos caracteres el límite estándar si tiene una buena
razón para hacerlo.
Registro de cambios
~~~~~~~~~~~~~~~~~~~
Y lo que es más importante, escriba los registros de cambios en modo
imperativo y evite los pronombres.
Consulte :ref:`describe_changes` para obtener más información, con una
recomendación: comience con un breve resumen de los cambios reales y
continúe con el contexto y los antecedentes. Nota. Este orden entra en
conflicto directo con el enfoque preferido del árbol de sugerencias. Por
favor, siga el estilo preferido del árbol de sugerencias cuando envíe
parches. que se dirigen principalmente a código arch/x86 que _NO_ es código
KVM.
KVM x86 prefiere indicar lo que hace un parche antes de entrar en detalles
por varias razones. En primer lugar, el código que realmente se está
cambiando es posiblemente la información más importante, por lo que esa
información debe ser fácil de encontrar. Changelogs que entierran el "qué
está cambiando realmente" en una sola línea después de 3+ párrafos de fondo
hacen muy difícil encontrar esa información.
Para la revisión inicial, se podría argumentar que "lo que está roto" es
más importante, pero para hojear los registros y la arqueología git, los
detalles escabrosos importan cada vez menos. Por ejemplo, al hacer una
serie de "git blame", los detalles de cada cambio a lo largo del camino son
inútiles, los detalles sólo importan para el culpable. Proporcionar el "qué
ha cambiado" facilita determinar rápidamente si una confirmación puede ser
de interés o no.
Otra ventaja de decir primero "qué cambia" es que casi siempre es posible
decir "qué cambia" en una sola frase. A la inversa, todo menos los errores
más simples requieren varias frases o párrafos para describir el problema.
Si tanto "qué está cambiando" como "cuál es el fallo" son muy breves, el
orden no importa. Pero si uno es más corto (casi siempre el "qué está
cambiando"), entonces cubrir el más corto primero es ventajoso porque es
menos inconveniente para los lectores/revisores que tienen una preferencia
estricta de orden. Por ejemplo, tener que saltarse una frase para llegar al
contexto es menos doloroso que tener que saltarse tres párrafos para llegar
a "lo que cambia".
Arreglos
~~~~~~~~
Si un cambio corrige un error de KVM/kernel, añada una etiqueta Fixes:
incluso si el cambio no necesita ser retroportado a kernels estables, e
incluso si el cambio corrige un error en una versión anterior.
Por el contrario, si es necesario hacer una corrección, etiquete
explícitamente el parche con "Cc: stable@vger.kernel" (aunque no es
necesario que el correo electrónico incluya Cc: stable); KVM x86 opta por
excluirse del backporting Correcciones: por defecto. Algunos parches
seleccionados automáticamente se retroportan, pero requieren la aprobación
explícita de los mantenedores (busque MANUALSEL).
Referencias a Funciones
~~~~~~~~~~~~~~~~~~~~~~~
Cuando se mencione una función en un comentario, registro de cambios o
registro abreviado (o en cualquier otro lugar), utilice el formato
``nombre_de_la_función()``. Los paréntesis proporcionan contexto y
desambiguan la referencia.
Pruebas
~~~~~~~
Como mínimo, *todos* los parches de una serie deben construirse limpiamente
para KVM_INTEL=m KVM_AMD=m, y KVM_WERROR=y. Construir todas las
combinaciones posibles de Kconfigs no es factible, pero cuantas más mejor.
KVM_SMM, KVM_XEN, PROVE_LOCKING, y X86_64 son particularmente interesantes.
También es obligatorio ejecutar las autopruebas y las pruebas unitarias de
KVM (y, como es obvio, las pruebas deben pasar). La única excepción es para
los cambios que tienen una probabilidad insignificante de afectar al
comportamiento en tiempo de ejecución, por ejemplo, parches que sólo
modificar los comentarios. Siempre que sea posible y pertinente, se
recomienda encarecidamente realizar pruebas tanto en Intel como en AMD. Se
recomienda arrancar una máquina virtual real, pero no es obligatorio.
Para cambios que afecten al código de paginación en la sombra de KVM, es
obligatorio ejecutar con TDP (EPT/NPT) deshabilitado. Para cambios que
afecten al código MMU común de KVM, se recomienda encarecidamente ejecutar
con TDP deshabilitado. Para todos los demás cambios, si el código que se
está modificando depende de y/o interactúa con un parámetro del módulo, es
obligatorio realizar pruebas con la configuración correspondiente.
Tenga en cuenta que las autopruebas de KVM y las pruebas de unidad de KVM
tienen fallos conocidos. Si sospecha que un fallo no se debe a sus cambios,
verifique que el *exactamente el mismo* fallo se produce con y sin sus
cambios.
Los cambios que afecten a la documentación de texto reestructurado, es
decir, a los archivos .rst, deben generar htmldocs de forma limpia, es
decir, sin advertencias ni errores.
Si no puede probar completamente un cambio, por ejemplo, por falta de
hardware, indique claramente qué nivel de pruebas ha podido realizar, por
ejemplo, en la carta de presentación.
Novedades
~~~~~~~~~
Con una excepción, las nuevas características *deben* venir con cobertura
de pruebas. Las pruebas específicas de KVM no son estrictamente necesarias,
por ejemplo, si la cobertura se proporciona mediante la ejecución de una
prueba de VM huésped suficientemente habilitada, o ejecutando una
autoprueba de kernel relacionada en una VM, pero en todos los casos se
prefieren las pruebas KVM dedicadas. Los casos de prueba negativos en
particular son obligatorios para la habilitación de nuevas características
de hardware, ya que los flujos de errores y excepciones rara vez se
ejercitan simplemente ejecutando una VM.
La única excepción a esta regla es si KVM está simplemente anunciando
soporte para un a través de KVM_GET_SUPPORTED_CPUID, es decir, para
instrucciones/funciones que KVM no puede impedir que utilice una VM y
para las que no existe una verdadera habilitación.
Tenga en cuenta que "nuevas características" no significa sólo "nuevas
características de hardware". Las nuevas funcionalidades que no puedan ser
validadas usando las pruebas existentes de KVM y/o las pruebas unitarias de
KVM deben venir con pruebas.
Es más que bienvenido el envío de nuevos desarrollos de características sin
pruebas para obtener un feedback temprano, pero tales envíos deben ser
etiquetados como RFC, y la carta de presentación debe indicar claramente
qué tipo de feedback se solicita/espera. No abuse del proceso de RFC; las
RFC no suelen recibir una revisión en profundidad.
Corrección de Errores
~~~~~~~~~~~~~~~~~~~~~
Salvo en el caso de fallos "obvios" detectados por inspección, las
correcciones deben ir acompañadas de un reproductor del fallo corregido. En
muchos casos, el reproductor está implícito, por ejemplo, para errores de
compilación y fallos de prueba, pero debe quedar claro para lectores qué es
lo que no funciona y cómo verificar la solución. Se concede cierto margen a
los errores detectados mediante cargas de trabajo/pruebas no públicas, pero
se recomienda encarecidamente que se faciliten pruebas de regresión para
dichos errores.
En general, las pruebas de regresión son preferibles para cualquier fallo
que no sea trivial de encontrar. Por ejemplo, incluso si el error fue
encontrado originalmente por un fuzzer como syzkaller, una prueba de
regresión dirigida puede estar justificada si el error requiere golpear una
condición de carrera de tipo uno en un millón.
Recuerde que los fallos de KVM rara vez son urgentes *y* no triviales de
reproducir. Pregúntate si un fallo es realmente el fin del mundo antes de
publicar una corrección sin un reproductor.
Publicación
-----------
Enlaces
~~~~~~~
No haga referencia explícita a informes de errores, versiones anteriores de
un parche/serie, etc. mediante cabeceras ``In-Reply-To:``. Usar
``In-Reply-To:`` se convierte en un lío para grandes series y/o cuando el
número de versiones es alto, y ``In-Reply-To:`` es inútil para cualquiera
que no tenga el mensaje original, por ejemplo, si alguien no recibió un Cc
en el informe de error o si la lista de destinatarios cambia entre
versiones.
Para enlazar con un informe de error, una versión anterior o cualquier cosa
de interés, utiliza enlaces lore. Para hacer referencia a versiones
anteriores, en general no incluya un Enlace: en el registro de cambios, ya
que no hay necesidad de registrar la historia en git, es decir, ponga el
enlace en la carta de presentación o en la sección que git ignora.
Proporcione un Enlace: formal para los informes de errores y/o discusiones
que condujeron al parche. El contexto de por qué se hizo un cambio es muy
valioso para futuros lectores.
Basado en Git
~~~~~~~~~~~~~
Si utilizas la versión 2.9.0 o posterior de git (Googlers, ¡os incluimos a
todos!), utilice ``git format-patch`` con el indicador ``--base`` para
incluir automáticamente la información del árbol base en los parches
generados.
Tenga en cuenta que ``--base=auto`` funciona como se espera si y sólo si el
upstream de una rama se establece en la rama temática base, por ejemplo,
hará lo incorrecto si su upstream se establece en su repositorio personal
con fines de copia de seguridad. Una solución "automática" alternativa es
derivar los nombres de tus ramas de desarrollo basándose en su KVM x86, e
introdúzcalo en ``--base``. Por ejemplo, ``x86/pmu/mi_nombre_de_rama``, y
luego escribir un pequeño wrapper para extraer ``pmu`` del nombre de la
rama actual para obtener ``--base=x/pmu``, donde ``x`` es el nombre que su
repositorio utiliza para rastrear el remoto KVM x86.
Tests de Co-Publicación
~~~~~~~~~~~~~~~~~~~~~~~
Las autopruebas de KVM asociadas a cambios de KVM, por ejemplo, pruebas de
regresión para correcciones de errores, deben publicarse junto con los
cambios de KVM como una única serie. Se aplicarán las reglas estándar del
núcleo para la bisección, es decir, los cambios de KVM que provoquen fallos
en las pruebas se ordenarán después de las actualizaciones de las
autopruebas, y viceversa. Las pruebas que fallan debido a errores de KVM
deben ordenarse después de las correcciones de KVM.
KVM-unit-tests debería *siempre* publicarse por separado. Las herramientas,
por ejemplo b4 am, no saben que KVM-unit-tests es un repositorio separado y
se confunden cuando los parches de una serie se aplican en diferentes
árboles. Para vincular los parches de KVM-unit-tests a Parches KVM, primero
publique los cambios KVM y luego proporcione un enlace lore Link: al
parche/serie KVM en el parche(s) KVM-unit-tests.
Notificaciones
~~~~~~~~~~~~~~
Cuando se acepte oficialmente un parche/serie, se enviará un correo
electrónico de notificación en respuesta a la publicación original (carta
de presentación para series de varios parches). La notificación incluirá el
árbol y la rama temática, junto con los SHA1 de los commits de los parches
aplicados.
Si se aplica un subconjunto de parches, se indicará claramente en la
notificación. A menos que se indique lo contrario, se sobreentiende que
todos los parches del Las series que no han sido aceptadas necesitan más
trabajo y deben presentarse en una nueva versión.
Si por alguna razón se retira un parche después de haber sido aceptado
oficialmente, se enviará una respuesta al correo electrónico de
notificación explicando por qué se ha retirado el parche, así como los
pasos siguientes.
Estabilidad SHA1
~~~~~~~~~~~~~~~~
Los SHA1 no son 100% estables hasta que llegan al árbol de Linus. Un SHA1
es *normalmente* estable una vez que se ha enviado una notificación, pero
ocurren cosas. En la mayoría de los casos, se proporcionará una
actualización del correo electrónico de notificación si se aplica un SHA1
del parche. Sin embargo, en algunos escenarios, por ejemplo, si todas las
ramas de KVM x86 necesitan ser rebasadas, no se darán notificaciones
individuales.
Vulnerabilidades
~~~~~~~~~~~~~~~~
Los fallos que pueden ser explotados por la VM (el "guest") para atacar al
host (kernel o espacio de usuario), o que pueden ser explotados por una VM
anidada a *su* host (L2 atacando a L1), son de particular interés para KVM.
Por favor, siga el protocolo para :ref:`securitybugs` si sospecha que un
fallo puede provocar una filtración de datos, etc.
@@ -0,0 +1,299 @@
.. include:: ../disclaimer-sp.rst
:Original: Documentation/process/management-style.rst
:Translator: Avadhut Naik <avadhut.naik@amd.com>
.. _sp_managementstyle:
Estilo de gestión del kernel de Linux
=====================================
Este es un documento breve que describe el estilo de gestión preferido (o
inventado, dependiendo de a quién le preguntes) para el kernel de Linux.
Está destinado a reflejar el documento
:ref:`translations/sp_SP/process/coding-style.rst <sp_codingstyle>` hasta
cierto punto y está escrito principalmente para evitar responder a [#f1]_
las mismas preguntas (o similares) una y otra vez.
El estilo de gestión es muy personal y mucho más difícil de cuantificar
que reglas simples de estilo de codificación, por lo que este documento
puede o no tener relación con la realidad. Comenzó como una broma, pero
eso no significa que no pueda ser realmente cierto. Tendrás que decidir
por ti mismo.
Por cierto, cuando se hable de “gerente de kernel”, se refiere a las
personas lideres técnicas, no de las personas que hacen la gestión
tradicional dentro de las empresas. Si firmas pedidos de compra o tienes
alguna idea sobre el presupuesto de tu grupo, es casi seguro que no eres
un gerente de kernel. Estas sugerencias pueden o no aplicarse a usted.
En primer lugar, sugeriría comprar “Seven Habits of Highly Effective
People” y NO leerlo. Quemarlo, es un gran gesto simbólico.
.. [#f1] Este documento lo hace no tanto respondiendo a la pregunta, sino
haciendo dolorosamente obvio para el interrogador que no tenemos ni idea
de cuál es la respuesta.
De todos modos, aquí va:
.. _decisiones:
1) Decisiones
-------------
Todos piensan que los gerentes toman decisiones, y que la toma de
decisiones en importante. Cuanto más grande y dolorosa sea la decisión,
más grande debe ser el gerente para tomarla. Eso es muy profundo y obvio,
pero en realidad no es cierto.
El nombre del partido es **evitar** tener que tomar una decisión. En
particular, si alguien te dice “elige (a) o (b), realmente necesitamos
que decidas sobre esto”, estas en problemas como gerente. Es mejor que
las personas a las que diriges conozcan los detalles mejor que tú, así
que, si acuden a ti para tomar una decisión técnica, estas jodido.
Claramente no eres competente para tomar una decisión por ellos.
(Corolario: Si las personas a las que diriges no conocen los detalles
mejor que tú, también estas jodido, aunque por una razón totalmente
diferente. Es decir, que estas en el trabajo equivocado y que **ellos**
deberían gestionando tu brillantez en su lugar).
Así que el nombre del partido es **evitar** las decisiones, al menos las
grandes y dolorosas. Tomar decisiones pequeñas y sin consecuencias está
bien, y te hace parecer que sabes lo que estás haciendo, así que lo que
un gerente de kernel necesita hacer es convertir las decisiones grandes
y dolorosas en cosas pequeñas a los que a nadie realmente le importa.
Ayuda darse cuenta de que la diferencia clave entre una decisión grande
y una pequeña es si puede arreglar su decisión después. Cualquier
decisión se puede hacer pequeña simplemente asegurándose siempre de que
si te equivocaste (u **estarás** equivocado), siempre puede deshacer el
daño más tarde retrocediendo. De repente, llegas a ser doblemente
gerencial por tomar **dos** decisiones intrascendentes - la equivocada
**y** la correcta.
Y las personas incluso verán eso como un verdadero liderazgo (*tos*
mierda *tos*).
Por lo tanto, la llave para evitar las grandes decisiones se convierte en
simplemente evitar hacer cosas que no se pueden deshacer. No te dejes
llevar a una esquina del que no puedas escapar. Una rata acorralada puede
ser peligrosa – un gerente acorralado es directamente lamentable.
Resulta que, dado que nadie sería tan estúpido como para dejar que un
gerente de kernel tenga una gran responsabilidad **de todos modos**,
generalmente es bastante fácil retroceder. Dado que no vas a poder
malgastar grandes cantidades de dinero que tal vez no puedas pagar, lo
único que puedes revertir es una decisión técnica, y ahí retroceder es
muy fácil: simplemente diles a todos que fuiste un bobo incompetente,
pide disculpas y deshaz todo el trabajo inútil que hiciste trabajar a la
gente durante el año pasado. De repente, la decisión que tomaste hace un
año no era una gran decisión después de todo, ya que se podía deshacer
fácilmente.
Resulta que algunas personas tienen problemas con este enfoque, por dos
razones:
- admitir que eras un idiota es más difícil de lo que parece. A todos
nos gusta mantener las apariencias, y salir en público a decir que te
equivocaste a veces es muy duro.
- que alguien te diga que lo que trabajaste durante el último año no
valió la pena después de todo también puede ser duro para los pobres
ingenieros humildes, y aunque el **trabajo** real fue bastante fácil
de deshacer simplemente eliminándolo, es posible que hayas perdido
irrevocablemente la confianza de ese ingeniero. Y recuerda:
“irrevocablemente” fue lo que tratamos de evitar en primer lugar, y
tu decisión terminó siendo muy grande después de todo.
Afortunadamente, estas dos razones pueden mitigarse eficazmente
simplemente admitiendo inicialmente que no tienes ni idea, y diciéndole
a la gente que tu decisión es puramente preliminar, y podría ser la cosa
equivocada. Siempre te debes reservar el derecho de cambiar de opinión, y
hacer que la gente sea muy **consciente** de eso. Y es mucho más fácil
admitir que eres estúpido cuando **aun** no has hecho la cosa realmente
estúpida.
Entonces, cuando realmente resulta ser estúpido, la gente simplemente
pone los ojos y dice “Ups, otra vez no”.
Esta admisión preventiva de incompetencia también podría hacer que las
personas que realmente hacen el trabajo piensen dos veces sobre si vale la
pena hacerlo o no. Después de todo, si **ellos** no están seguros de si es
una buena idea, seguro que no deberías alentarlos prometiéndoles que lo
que trabajan será incluido. Haz que al menos lo piensen dos veces antes de
embarcarse en un gran esfuerzo.
Recuerda: Es mejor que sepan más sobre los detalles que tú, y
generalmente ya piensan que tienen la respuesta a todo. Lo mejor que puede
hacer como gerente no es inculcar confianza, sino más bien una dosis
saludable de pensamiento crítico sobre lo que hacen.
Por cierto, otra forma de evitar una decisión es quejarse lastimeramente
de “no podemos hacer ambas cosas?” y parecer lamentable. Créeme, funciona.
Si no está claro cuál enfoque es mejor, lo descubrirán. La respuesta puede
terminar siendo que ambos equipos se sientan tan frustrados por la
situación que simplemente se den por vencidos.
Eso puede sonar como un fracaso, pero generalmente es una señal de que
había algo mal con ambos proyectos, y la razón por la que las personas
involucradas no pudieron decidir fue que ambos estaban equivocados.
Terminas oliendo a rosas y evitaste otra decisión que podrías haber
metido la pata.
2) Gente
--------
La mayoría de las personas son idiotas, y ser gerente significa que
tendrás que lidiar con eso, y quizás lo más importante, que **ellos**
tienen que lidiar **contigo**.
Resulta que, si bien es fácil deshacer los errores técnicos, no es tan
fácil deshacer los trastornos de personalidad. Solo tienes que vivir
con los suyos - y el tuyo.
Sin embargo, para prepararse como gerente del kernel, es mejor recordar
no quemar ningún puente, bombardear a ningún aldeano inocente o alienar
a demasiados desarrolladores del kernel. Resulta que alienar a las
personas es bastante fácil, y desalienarlas es difícil. Por lo tanto,
“alienar” cae inmediatamente debajo del título “no reversible”, y se
convierte en un no-no según :ref:`decisiones`.
Aquí solo hay algunas reglas simples:
(1) No llames a la gente pen*ejos (al menos no en público)
(2) Aprende a disculparte cuando olvidaste la regla (1)
El problema con #1 es que es muy fácil de hacer, ya que puedes decir
“eres un pen*ejo” de millones de manera diferentes [#f2]_, a veces sin
siquiera darte cuenta, y casi siempre con una convicción ardiente de que
tienes razón.
Y cuanto más convencido estés de que tienes razón (y seamos sinceros,
puedes llamar a casi **cualquiera** un pen*ejo, y a menudo **tendrás**
razón), más difícil termina siendo disculparse después.
Para resolver este problema, realmente solo tienes dos opciones:
- Se muy buenos en las disculpas.
- Difunde el “amor” de manera tan uniforme que nadie termina sintiendo
que es atacado injustamente. Hazlo lo suficientemente ingenioso, e
incluso podría divertirse.
La opción de ser infaliblemente educado realmente no existe. Nadie
confiará en alguien que está ocultando tan claramente su verdadero
carácter.
.. [#f2] Paul Simon cantó “Cincuenta maneras de dejar a tu amante” porque,
francamente, “Un millón de maneras de decirle a un desarrollador que es
un pen*ejo” no escanea tan bien. Pero estoy seguro de que lo pensó.
3) Gente II – el Buen Tipo
--------------------------
Aunque resulta que la mayoría de las personas son idiotas, el corolario
de eso es, tristemente, que tú también seas uno, y aunque todos podemos
disfrutar del conocimiento seguro de que somos mejores que la persona
promedio (somos realistas, nadie cree que nunca que son promedio o debajo
del promedio), también debemos admitir que no somos el cuchillo más
afilado alrededor, y habrá otras personas que son menos idiotas que tú.
Algunas personas reaccionan mal a las personas inteligentes. Otras se
aprovechan de ellos.
Asegúrate de que tú, como mantenedor del kernel, estás en el segundo
grupo. Aguanta con ellos, porque son las personas que te facilitarán el
trabajo. En particular, podrán tomar tus decisiones por ti, que es de lo
que se trata el juego.
Así que cuando encuentras a alguien más inteligente que tú, simplemente
sigue adelante. Sus responsabilidades de gestión se convierten en gran
medida en las de decir “Suena como una buena idea, - hazlo sin
restricciones”, o “Eso suena bien, pero ¿qué pasa con xxx?". La segunda
versión en particular es una excelente manera de aprender algo nuevo
sobre “xxx” o parecer **extra** gerencial al señalar algo que la persona
más inteligente no había pensado. En cualquier caso, sales ganando.
Una cosa para tener en cuenta es darse cuenta de que la grandeza en un
área no necesariamente se traduce en otras áreas. Así que puedes impulsar
a la gente en direcciones específicas, pero seamos realistas, pueden ser
buenos en lo que hacen, y ser malos en todo lo demás. La buena noticia es
que las personas tienden a gravitar naturalmente hacia lo que son buenos,
por lo que no es como si estuvieras haciendo algo irreversible cuando los
impulsas en alguna dirección, simplemente no presiones demasiado.
4) Colocar la culpa
-------------------
Las cosas saldrán mal, y la gente quiere culpar a alguien. Etiqueta, tú
lo eres.
En realidad, no es tan difícil aceptar la culpa, especialmente si la gente
se da cuenta de que no fue **toda** tu culpa. Lo que nos lleva a la mejor
manera de asumir la culpa: hacerlo por otra persona. Te sentirás bien por
asumir la caída, ellos se sentirán bien por no ser culpados, y la persona
que perdió toda su colección de pornografía de 36 GB debido a tu
incompetencia admitirá a regañadientes que al menos intentaste escapar
de ella.
Luego haz que el desarrollador que realmente metió la pata (si puedes
encontrarlo) sepa **en privado** que metió la pata. No solo para que
pueda evitarlo en futuro, sino para que sepan que te deben uno. Y, quizás
aún más importante, también es probable que sea la persona que puede
solucionarlo. Porque, seamos sinceros, seguro que no eres tú.
Asumir la culpa también es la razón por la que llegas a ser un gerente
en primer lugar. Es parte de lo que hace que la gente confíe en ti y te
permita la gloria potencial porque eres tú quien puede decir “metí la
pata”. Y si has seguido las reglas anteriores, ya serás bastante bueno
para decir eso.
5) Cosas que evitar
-------------------
Hay una cosa que la gente odia incluso más que ser llamado “pen*ejo”,
y que es ser llamado “pen*ejo” en una voz mojigata. Por lo primero,
puedes disculparte, por lo segundo, realmente, no tendrás la oportunidad.
Es probable que ya no estén escuchando, incluso si de lo contrario haces
un buen trabajo.
Todos pensamos que somos mejores que los demás, lo que significa que
cuando alguien más se da aires, **realmente** nos molesta. Puedes ser
moral e intelectualmente superior a todos los que te rodean, pero no
trates de hacerlo demasiado obvio a menos que tengas **la intención**
real de irritar a alguien [#f3]_.
Del mismo modo, no seas demasiado educado o sutil acerca de las cosas. La
cortesía fácilmente termina yendo demasiado lejos y ocultado el problema,
y como dicen “En internet, nadie puede oírte ser sutil”. Usa un gran
objeto contundente para enfatizar el punto, porque realmente no puedes
depender de que las personas entiendan tu punto de otra manera.
Un poco de humor puede ayudar a suavizar tanto la franqueza como la
moralización. Exagerar hasta el punto de ser ridículo puede reforzar un
punto sin hacer que sea doloroso para el destinatario, quien simplemente
piensa que estas siendo tonto. Por lo tanto, puede ayudarnos a superar el
bloqueo mental personal que todos tenemos sobre la crítica.
.. [#f3] La pista: Los grupos de noticias de Internet que no están
directamente relacionados con tu trabajo son excelentes maneras de
desahogar tus frustraciones con otras personas. Escribe mensajes
insultantes con una mueca de desprecio solo para entrar en un humor de
vez en cuando, y te sentirás limpio. Eso sí, no te cagues demasiado
cerca de casa.
6) ¿Por qué a mí?
-----------------
Dado que tu principal responsabilidad parece ser asumir la culpa de los
errores de otras personas y hacer dolorosamente obvio para todos los
demás que eres incompetente, la pregunta obvia es: ¿por qué hacerlo en
primer lugar?
Pase lo que pase, **tendrás** una sensación inmensa de logro personal por
estar “a cargo”. No importa el hecho de que realmente estés liderando al
tratar de mantenerte al día con todos los demás y correr detrás de ellos
lo más rápido que puedes. Todo el mundo seguirá pensando que eres la
persona a cargo.
Es un gran trabajo si puedes descifrarlo.
@@ -0,0 +1,53 @@
.. include:: ../disclaimer-sp.rst
:Original: :ref:`Documentation/process/programming-language.rst <programming_language>`
:Translator: Carlos Bilbao <carlos.bilbao.osdev@gmail.com>
.. _sp_programming_language:
Lenguaje de programación
========================
El kernel está escrito en el lenguaje de programación C [sp-c-language]_.
Más concretamente, el kernel normalmente se compila con ``gcc`` [sp-gcc]_
bajo ``-std=gnu11`` [sp-gcc-c-dialect-options]_: el dialecto GNU de ISO C11.
``clang`` [sp-clang]_ también es compatible, consulte los documentos en
:ref:`Building Linux with Clang/LLVM <kbuild_llvm>`.
Este dialecto contiene muchas extensiones del lenguaje [sp-gnu-extensions]_,
y muchos de ellos se usan dentro del kernel de forma habitual.
Hay algo de soporte para compilar el núcleo con ``icc`` [sp-icc]_ para varias
de las arquitecturas, aunque en el momento de escribir este texto, eso no
está terminado y requiere parches de terceros.
Atributos
---------
Una de las comunes extensiones utilizadas en todo el kernel son los atributos
[sp-gcc-attribute-syntax]_. Los atributos permiten introducir semántica
definida por la implementación a las entidades del lenguaje (como variables,
funciones o tipos) sin tener que hacer cambios sintácticos significativos
al idioma (por ejemplo, agregar una nueva palabra clave) [sp-n2049]_.
En algunos casos, los atributos son opcionales (es decir, hay compiladores
que no los admiten pero de todos modos deben producir el código adecuado,
incluso si es más lento o no realiza tantas comprobaciones/diagnósticos en
tiempo de compilación).
El kernel define pseudo-palabras clave (por ejemplo, ``__pure``) en lugar
de usar directamente la sintaxis del atributo GNU (por ejemplo,
``__attribute__((__pure__))``) con el fin de detectar cuáles se pueden
utilizar y/o acortar el código.
Por favor consulte ``include/linux/compiler_attributes.h`` para obtener
más información.
.. [sp-c-language] http://www.open-std.org/jtc1/sc22/wg14/www/standards
.. [sp-gcc] https://gcc.gnu.org
.. [sp-clang] https://clang.llvm.org
.. [sp-icc] https://software.intel.com/en-us/c-compilers
.. [sp-gcc-c-dialect-options] https://gcc.gnu.org/onlinedocs/gcc/C-Dialect-Options.html
.. [sp-gnu-extensions] https://gcc.gnu.org/onlinedocs/gcc/C-Extensions.html
.. [sp-gcc-attribute-syntax] https://gcc.gnu.org/onlinedocs/gcc/Attribute-Syntax.html
.. [sp-n2049] http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2049.pdf
@@ -0,0 +1,150 @@
.. SPDX-License-Identifier: GPL-2.0
:Original: :ref:`Documentation/process/researcher-guidelines.rst`
:Translator: Avadhut Naik <avadhut.naik@amd.com>
Directrices para Investigadores
++++++++++++++++++++++++++++++++
La comunidad del kernel de Linux da la bienvenida a la investigación
transparente sobre el kernel de Linux, las actividades involucradas
en su producción, otros subproductos de su desarrollo. Linux se
beneficia mucho de este tipo de investigación, y la mayoría de los
aspectos de Linux son impulsados por investigación en una forma u otra.
La comunidad agradece mucho si los investigadores pueden compartir
los hallazgos preliminares antes de hacer públicos sus resultados,
especialmente si tal investigación involucra seguridad. Involucrarse
temprano ayuda a mejorar la calidad de investigación y la capacidad
de Linux para mejorar a partir de ella. En cualquier caso, se recomienda
compartir copias de acceso abierto de la investigación publicada con
la comunidad.
Este documento busca clarificar lo que la comunidad del kernel de Linux
considera practicas aceptables y no aceptables al llevar a cabo
investigación de este tipo. Por lo menos, dicha investigación y
actividades afines deben seguir las reglas estándar de ética de la
investigación. Para más información sobre la ética de la investigación
en general, ética en la tecnología y la investigación de las comunidades
de desarrolladores en particular, ver:
* `Historia de la Ética en la Investigación <https://www.unlv.edu/research/ORI-HSR/history-ethics>`_
* `Ética de la IEEE <https://www.ieee.org/about/ethics/index.html>`_
* `Perspectivas de Desarrolladores e Investigadores sobre la Ética de los Experimentos en Proyectos de Código Abierto <https://arxiv.org/pdf/2112.13217.pdf>`_
La comunidad del kernel de Linux espera que todos los que interactúan con
el proyecto están participando en buena fe para mejorar Linux. La
investigación sobre cualquier artefacto disponible públicamente (incluido,
pero no limitado a código fuente) producido por la comunidad del kernel
de Linux es bienvenida, aunque la investigación sobre los desarrolladores
debe ser claramente opcional.
La investigación pasiva que se basa completamente en fuentes disponibles
públicamente, incluidas las publicaciones en listas de correo públicas y
las contribuciones a los repositorios públicos, es claramente permitida.
Aunque, como con cualquier investigación, todavía se debe seguir la ética
estándar.
La investigación activa sobre el comportamiento de los desarrolladores,
sin embargo, debe hacerse con el acuerdo explícito y la divulgación
completa a los desarrolladores individuales involucrados. No se puede
interactuar / experimentar con los desarrolladores sin consentimiento;
esto también es ética de investigación estándar.
Para ayudar a aclarar: enviar parches a los desarrolladores es interactuar
con ellos, pero ya han dado su consentimiento para recibir contribuciones
en buena fe. No se ha dado consentimiento para enviar parches intencionalmente
defectuosos / vulnerables o contribuir con la información engañosa a las
discusiones. Dicha comunicación puede ser perjudicial al desarrollador (por
ejemplo, agotar el tiempo, el esfuerzo, y la moral) y perjudicial para el
proyecto al erosionar la confianza de toda la comunidad de desarrolladores en
el colaborador (y la organización del colaborador en conjunto), socavando
los esfuerzos para proporcionar reacciones constructivas a los colaboradores
y poniendo a los usuarios finales en riesgo de fallas de software.
La participación en el desarrollo de Linux en sí mismo por parte de
investigadores, como con cualquiera, es bienvenida y alentada. La
investigación del código de Linux es una práctica común, especialmente
cuando se trata de desarrollar o ejecutar herramientas de análisis que
producen resultados procesables.
Cuando se interactúa con la comunidad de desarrolladores, enviar un
parche ha sido tradicionalmente la mejor manera para hacer un impacto.
Linux ya tiene muchos errores conocidos – lo que es mucho más útil es
tener soluciones verificadas. Antes de contribuir, lea cuidadosamente
la documentación adecuada.
* Documentation/process/development-process.rst
* Documentation/process/submitting-patches.rst
* Documentation/admin-guide/reporting-issues.rst
* Documentation/process/security-bugs.rst
Entonces envíe un parche (incluyendo un registro de confirmación con
todos los detalles enumerados abajo) y haga un seguimiento de cualquier
comentario de otros desarrolladores.
* ¿Cuál es el problema específico que se ha encontrado?
* ¿Como podría llegar al problema en un sistema en ejecución?
* ¿Qué efecto tendría encontrar el problema en el sistema?
* ¿Como se encontró el problema? Incluya específicamente detalles sobre
cualquier prueba, programas de análisis estáticos o dinámicos, y cualquier
otra herramienta o método utilizado para realizar el trabajo.
* ¿En qué versión de Linux se encontró el problema? Se prefiere usar la
versión más reciente o una rama reciente de linux-next (ver
Documentation/process/howto.rst).
* ¿Que se cambió para solucionar el problema y por qué se cree es correcto?
* ¿Como se probó el cambio para la complicación y el tiempo de ejecución?
* ¿Qué confirmación previa corrige este cambio? Esto debería ir en un “Fixes:”
etiqueta como se describe en la documentación.
* ¿Quién más ha revisado este parche? Esto debería ir con la adecuada “Reviewed-by”
etiqueta; Vea abajo.
Por ejemplo (en inglés, pues es en las listas)::
From: Author <author@email>
Subject: [PATCH] drivers/foo_bar: Add missing kfree()
The error path in foo_bar driver does not correctly free the allocated
struct foo_bar_info. This can happen if the attached foo_bar device
rejects the initialization packets sent during foo_bar_probe(). This
would result in a 64 byte slab memory leak once per device attach,
wasting memory resources over time.
This flaw was found using an experimental static analysis tool we are
developing, LeakMagic[1], which reported the following warning when
analyzing the v5.15 kernel release:
path/to/foo_bar.c:187: missing kfree() call?
Add the missing kfree() to the error path. No other references to
this memory exist outside the probe function, so this is the only
place it can be freed.
x86_64 and arm64 defconfig builds with CONFIG_FOO_BAR=y using GCC
11.2 show no new warnings, and LeakMagic no longer warns about this
code path. As we don't have a FooBar device to test with, no runtime
testing was able to be performed.
[1] https://url/to/leakmagic/details
Reported-by: Researcher <researcher@email>
Fixes: aaaabbbbccccdddd ("Introduce support for FooBar")
Signed-off-by: Author <author@email>
Reviewed-by: Reviewer <reviewer@email>
Si usted es un colaborador por primera vez, se recomienda que el parche en
si sea examinado por otros en privado antes de ser publicado en listas
públicas. (Esto es necesario si se le ha dicho explícitamente que sus parches
necesitan una revisión interna más cuidadosa.) Se espera que estas personas
tengan su etiqueta “Reviewed-by” incluida en el parche resultante. Encontrar
otro desarrollador con conocimiento de las contribuciones a Linux, especialmente
dentro de su propia organización, y tener su ayuda con las revisiones antes de
enviarlas a las listas de correo publico tiende a mejorar significativamente la
calidad de los parches resultantes, y reduce así la carga de otros desarrolladores.
Si no se puede encontrar a nadie para revisar internamente los parches y necesita
ayuda para encontrar a esa persona, o si tiene alguna otra pregunta relacionada
con este documento y las expectativas de la comunidad de desarrolladores, por
favor contacte con la lista de correo privada Technical Advisory Board:
<tech-board@groups.linuxfoundation.org>.
@@ -0,0 +1,103 @@
.. SPDX-License-Identifier: GPL-2.0
.. include:: ../disclaimer-sp.rst
:Original: Documentation/process/security-bugs.rst
:Translator: Avadhut Naik <avadhut.naik@amd.com>
Errores de seguridad
====================
Los desarrolladores del kernel de Linux se toman la seguridad muy en
serio. Como tal, nos gustaría saber cuándo se encuentra un error de
seguridad para que pueda ser corregido y divulgado lo más rápido posible.
Por favor, informe sobre los errores de seguridad al equipo de seguridad
del kernel de Linux.
Contacto
--------
El equipo de seguridad del kernel de Linux puede ser contactado por correo
electrónico en <security@kernel.org>. Esta es una lista privada de
oficiales de seguridad que ayudarán a verificar el informe del error y
desarrollarán y publicarán una corrección. Si ya tiene una corrección, por
favor, inclúyala con su informe, ya que eso puede acelerar considerablemente
el proceso. Es posible que el equipo de seguridad traiga ayuda adicional
de mantenedores del área para comprender y corregir la vulnerabilidad de
seguridad.
Como ocurre con cualquier error, cuanta más información se proporcione,
más fácil será diagnosticarlo y corregirlo. Por favor, revise el
procedimiento descrito en 'Documentation/admin-guide/reporting-issues.rst'
si no tiene claro que información es útil. Cualquier código de explotación
es muy útil y no será divulgado sin el consentimiento del "reportero" (el
que envia el error) a menos que ya se haya hecho público.
Por favor, envíe correos electrónicos en texto plano sin archivos
adjuntos cuando sea posible. Es mucho más difícil tener una discusión
citada en contexto sobre un tema complejo si todos los detalles están
ocultos en archivos adjuntos. Piense en ello como un
:doc:`envío de parche regular <submitting-patches>` (incluso si no tiene
un parche todavía) describa el problema y el impacto, enumere los pasos
de reproducción, y sígalo con una solución propuesta, todo en texto plano.
Divulgación e información embargada
-----------------------------------
La lista de seguridad no es un canal de divulgación. Para eso, ver
Coordinación debajo. Una vez que se ha desarrollado una solución robusta,
comienza el proceso de lanzamiento. Las soluciones para errores conocidos
públicamente se lanzan inmediatamente.
Aunque nuestra preferencia es lanzar soluciones para errores no divulgados
públicamente tan pronto como estén disponibles, esto puede postponerse a
petición del reportero o una parte afectada por hasta 7 días calendario
desde el inicio del proceso de lanzamiento, con una extensión excepcional
a 14 días de calendario si se acuerda que la criticalidad del error requiere
más tiempo. La única razón válida para aplazar la publicación de una
solución es para acomodar la logística de QA y los despliegues a gran
escala que requieren coordinación de lanzamiento.
Si bien la información embargada puede compartirse con personas de
confianza para desarrollar una solución, dicha información no se publicará
junto con la solución o en cualquier otro canal de divulgación sin el
permiso del reportero. Esto incluye, pero no se limita al informe original
del error y las discusiones de seguimiento (si las hay), exploits,
información sobre CVE o la identidad del reportero.
En otras palabras, nuestro único interés es solucionar los errores. Toda
otra información presentada a la lista de seguridad y cualquier discusión
de seguimiento del informe se tratan confidencialmente incluso después de
que se haya levantado el embargo, en perpetuidad.
Coordinación con otros grupos
-----------------------------
El equipo de seguridad del kernel recomienda encarecidamente que los
reporteros de posibles problemas de seguridad NUNCA contacten la lista
de correo “linux-distros” hasta DESPUES de discutirlo con el equipo de
seguridad del kernel. No Cc: ambas listas a la vez. Puede ponerse en
contacto con la lista de correo linux-distros después de que se haya
acordado una solución y comprenda completamente los requisitos que al
hacerlo le impondrá a usted y la comunidad del kernel.
Las diferentes listas tienen diferentes objetivos y las reglas de
linux-distros no contribuyen en realidad a solucionar ningún problema de
seguridad potencial.
Asignación de CVE
-----------------
El equipo de seguridad no asigna CVEs, ni los requerimos para informes o
correcciones, ya que esto puede complicar innecesariamente el proceso y
puede retrasar el manejo de errores. Si un reportero desea que se le
asigne un identificador CVE, debe buscar uno por sí mismo, por ejemplo,
poniéndose en contacto directamente con MITRE. Sin embargo, en ningún
caso se retrasará la inclusión de un parche para esperar a que llegue un
identificador CVE.
Acuerdos de no divulgación
--------------------------
El equipo de seguridad del kernel de Linux no es un organismo formal y,
por lo tanto, no puede firmar cualquier acuerdo de no divulgación.
@@ -0,0 +1,134 @@
.. include:: ../disclaimer-sp.rst
:Original: Documentation/process/submit-checklist.rst
:Translator: Avadhut Naik <avadhut.naik@amd.com>
.. _sp_submitchecklist:
Lista de comprobación para enviar parches del kernel de Linux
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Aquí hay algunas cosas básicas que los desarrolladores deben hacer si
quieren que sus envíos de parches del kernel sean aceptados más
rápidamente.
Todo esto está más allá de la documentación que se proporciona en
:ref:`Documentation/translations/sp_SP/process/submitting-patches.rst <sp_submittingpatches>`
y en otros lugares con respecto al envío de parches del kernel de Linux.
1) Si utiliza una funcionalidad, #include el archivo que define/declara
esa funcionalidad. No dependa de otros archivos de encabezado que
extraigan los que utiliza.
2) Compile limpiamente:
a) Con las opciones ``CONFIG`` aplicables o modificadas ``=y``, ``=m``,
y ``=n``. Sin advertencias/errores del compilador ``gcc``, ni
advertencias/errores del linker.
b) Aprobar ``allnoconfig``, ``allmodconfig``
c) Compila correctamente cuando se usa ``O=builddir``
d) Cualquier documentación o cambios se compilan correctamente sin
nuevas advertencias/errores. Utilice ``make htmldocs`` o
``make pdfdocs`` para comprobar la compilación y corregir cualquier
problema.
3) Se compila en varias arquitecturas de CPU mediante herramientas de
compilación cruzada locales o alguna otra granja de compilación.
4) ppc64 es una buena arquitectura para verificar la compilación cruzada
por que tiende a usar ``unsigned long`` para cantidades de 64-bits.
5) Verifique su parche para el estilo general según se detalla en
:ref:`Documentation/translations/sp_SP/process/coding-style.rst <sp_codingstyle>`.
Verifique las infracciones triviales con el verificador de estilo de
parches antes de la entrega (``scripts/checkpatch.pl``).
Debería ser capaz de justificar todas las infracciones que permanezcan
en su parche.
6) Cualquier opción ``CONFIG`` nueva o modificada no altera el menú de
configuración y se desactiva por defecto, a menos que cumpla con los
criterios de excepción documentados en
``Documentation/kbuild/kconfig-language.rst`` Atributos del menú: valor por defecto.
7) Todas las nuevas opciones de ``Kconfig`` tienen texto de ayuda.
8) Ha sido revisado cuidadosamente con respecto a las combinaciones
relevantes de ``Kconfig``. Esto es muy difícil de hacer correctamente
con las pruebas -- la concentración mental da resultados aquí.
9) Verifique limpiamente con sparse.
10) Use ``make checkstack`` y solucione cualquier problema que encuentre.
.. note::
``checkstack`` no señala los problemas explícitamente, pero
cualquier función que use más de 512 bytes en la pila es
candidata para el cambio.
11) Incluya :ref:`kernel-doc <kernel_doc>` para documentar las API
globales del kernel. (No es necesario para funciones estáticas, pero
también está bien.) Utilice ``make htmldocs`` o ``make pdfdocs``
para comprobar el :ref:`kernel-doc <kernel_doc>` y solucionar
cualquier problema.
12) Ha sido probado con ``CONFIG_PREEMPT``, ``CONFIG_DEBUG_PREEMPT``,
``CONFIG_SLUB_DEBUG``, ``CONFIG_DEBUG_PAGEALLOC``, ``CONFIG_DEBUG_MUTEXES``,
``CONFIG_DEBUG_SPINLOCK``, ``CONFIG_DEBUG_ATOMIC_SLEEP``
``CONFIG_PROVE_RCU`` y ``CONFIG_DEBUG_OBJECTS_RCU_HEAD`` todos
habilitados simultáneamente.
13) Ha sido probado en tiempo de compilación y ejecución con y sin
``CONFIG_SMP`` y ``CONFIG_PREEMPT``.
14) Todas las rutas de código se han ejercido con todas las
características de lockdep habilitadas.
15) Todas las nuevas entradas de ``/proc`` están documentadas en
``Documentation/``.
16) Todos los nuevos parámetros de arranque del kernel están documentados
en ``Documentation/admin-guide/kernel-parameters.rst``.
17) Todos los nuevos parámetros del módulo están documentados con
``MODULE_PARM_DESC()``.
18) Todas las nuevas interfaces de espacio de usuario están documentadas
en ``Documentation/ABI/``. Consulte Documentation/admin-guide/abi.rst
(o ``Documentation/ABI/README``) para obtener más información.
Los parches que cambian las interfaces del espacio de usuario deben
ser CCed a linux-api@vger.kernel.org.
19) Se ha comprobado con la inyección de al menos errores de asignación
de slab y página. Consulte ``Documentation/fault-injection/``.
Si el nuevo código es sustancial, la adición de la inyección de
errores específica del subsistema podría ser apropiada.
20) El nuevo código añadido ha sido compilado con ``gcc -W`` (use
``make KCFLAGS=-W``). Esto generara mucho ruido per es buena para
encontrar errores como "warning: comparison between signed and unsigned".
21) Se prueba después de que se haya fusionado en el conjunto de
parches -mm para asegurarse de que siga funcionando con todos los
demás parches en cola y varios cambios en VM, VFS y otros subsistemas.
22) Todas las barreras de memoria {p.ej., ``barrier()``, ``rmb()``,
``wmb()``} necesitan un comentario en el código fuente que explique
la lógica de lo que están haciendo y por qué.
23) Si se añaden algún ioctl en el parche, actualice también
``Documentation/userspace-api/ioctl/ioctl-number.rst``.
24) Si su código fuente modificado depende o utiliza cualquiera de las
API o características del kernel que están relacionadas con los
siguientes símbolos ``Kconfig`` entonces pruebe varias compilaciones
con los símbolos ``Kconfig`` relacionados deshabilitados y/o ``=m``
(si esa opción esta disponible) [no todos estos al mismo tiempo, solo
varias/aleatorias combinaciones de ellos]:
``CONFIG_SMP``, ``CONFIG_SYSFS``, ``CONFIG_PROC_FS``, ``CONFIG_INPUT``, ``CONFIG_PCI``, ``CONFIG_BLOCK``, ``CONFIG_PM``, ``CONFIG_MAGIC_SYSRQ``
``CONFIG_NET``, ``CONFIG_INET=n`` (pero luego con ``CONFIG_NET=y``).
@@ -0,0 +1,919 @@
.. include:: ../disclaimer-sp.rst
:Original: :ref:`Documentation/process/submitting-patches.rst <submittingpatches>`
:Translator: Carlos Bilbao <carlos.bilbao.osdev@gmail.com>
.. _sp_submittingpatches:
Envío de parches: la guía esencial para incluir su código en el kernel
=======================================================================
Para una persona o empresa que desee enviar un cambio al kernel Linux,
el proceso puede en ocasiones resultar desalentador si no se está
familiarizado con "el sistema". Este texto es una colección de sugerencias
que pueden aumentar considerablemente las posibilidades de que se acepte su
cambio.
Este documento contiene una gran cantidad de sugerencias en un formato
relativamente conciso. Para obtener información detallada sobre cómo
funciona el proceso de desarrollo del kernel, consulte
Documentation/process/development-process.rst. Además, lea
Documentation/process/submit-checklist.rst para obtener una lista de
elementos a verificar antes de enviar código. Para los parches de
"binding" del árbol de dispositivos, lea
Documentation/devicetree/bindings/submitting-patches.rst.
Esta documentación asume que está usando ``git`` para preparar sus parches.
Si no está familiarizado con ``git``, le recomendamos que aprenda a
usarlo, le hará la vida como desarrollador del kernel y en general mucho
más sencilla.
Algunos subsistemas y árboles de mantenimiento cuentan con información
adicional sobre su flujo de trabajo y expectativas, consulte
Documentation/process/maintainer-handbooks.rst.
Obtenga el código fuente actual
--------------------------------
Si no tiene a mano un repositorio con el código fuente actual del kernel,
use ``git`` para obtener uno. Querrá comenzar con el repositorio principal,
que se puede descargar con::
git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
Tenga en cuenta, sin embargo, que es posible que no desee desarrollar con
el árbol principal directamente. La mayoría de los maintainers de
subsistemas usan sus propios árboles de código fuente y quieren ver parches
preparados para esos árboles. Revise el campo **T:** para el subsistema
en el archivo MAINTAINERS para encontrar dicho árbol, o simplemente
pregunte al maintainer si el árbol no está listado allí.
.. _sp_describe_changes:
Describa sus cambios
---------------------
Describa su problema. Sea su parche una corrección de un error de una
línea o 5000 líneas para una nuevo "feature", debe haber un problema
subyacente que le motivó a hacer ese trabajo. Convenza al revisor de que
hay un problema que merece la pena solucionar y de que tiene sentido que
lea más allá del primer párrafo.
Describa el impacto relativo al usuario. Cosas que estropeen el kernel y
los bloqueos son bastante convincentes, pero no todos los errores son tan
evidentes. Incluso si se detectó un problema durante la revisión del
código, describa el impacto que cree pueda tener en los usuarios. Tenga en
cuenta que la mayoría de instalaciones de Linux ejecutan kernels desde
árboles estables secundarios o árboles específicos de proveedor/producto
que seleccionan ("cherry-pick") solo parches específicos de upstream, así
que incluya cualquier cosa que pueda ayudar a dirigir su cambio
aguas abajo: circunstancias que producen cierta situación, extractos de
dmesg, descripciones del error fatal, regresiones de rendimiento, picos de
latencia, bloqueos, etc.
Cuantifique optimizaciones y beneficios/perdidas. Si asegura mejoras en
rendimiento, consumo de memoria, huella del stack o tamaño de binario,
incluya números que lo respalden. Pero también describa costes no obvios.
Las optimizaciones generalmente no son gratuitas, sino un equilibrio entre
CPU, memoria y legibilidad; o, cuando se trata de heurísticas, entre
diferentes cargas de trabajo. Describa las desventajas esperadas de su
optimización para que el revisor pueda comparar las perdidas con los
beneficios.
Una vez establecido el problema, describa lo que realmente está haciendo
al respecto en detalles técnicos. Es importante describir el cambio en
lenguaje sencillo para que el revisor verifique que el código se está
comportando como se pretende.
El maintainer le agradecerá que escriba la descripción de su parche en un
formato que se pueda incorporar fácilmente en la gestión del código fuente
del sistema, ``git``, como un "commit log" (registros de los commits).
Consulte :ref:`sp_the_canonical_patch_format`.
Resuelva solo un problema por parche. Si su descripción comienza a ser muy
larga, eso es una señal de que probablemente necesite dividir su parche.
Lea :ref:`split_changes`.
Cuando envíe o vuelva a enviar un parche o una serie de parches, incluya la
descripción completa del parche y justificación del mismo. No se limite a
decir que esa es la versión N del parche (serie). No espere que el
maintainer del subsistema referencie versiones de parches anteriores o use
referencias URL para encontrar la descripción del parche y colocarla en el
parche. Es decir, el parche (serie) y su descripción deben ser
independientes. Esto beneficia tanto a los maintainers como a los
revisores. Algunos revisores probablemente ni siquiera recibieran versiones
anteriores del parche.
Describa sus cambios en la forma imperativa, por ejemplo, "hacer que xyzzy
haga frotz" en lugar de "[Este parche] hace que xyzzy haga frotz" o "[Yo]
Cambié xyzzy para que haga frotz", como si estuviera dando órdenes al
código fuente para cambiar su comportamiento.
Si desea hacer referencia a un commit específico, no se limite a hacer
referencia al ID SHA-1 del commit. Incluya también el resumen de una línea
del commit, para que sea más fácil para los revisores saber de qué se
trata.
Ejemplo::
Commit e21d2170f36602ae2708 ("video: quitar platform_set_drvdata()
innecesario") eliminó innecesario platform_set_drvdata(), pero dejó la
variable "dev" sin usar, bórrese.
También debe asegurarse de utilizar al menos los primeros doce caracteres
del identificador SHA-1. El repositorio del kernel contiene muchos *muchos*
objetos, por lo que las colisiones con identificaciones más cortas son una
posibilidad real. Tenga en cuenta que, aunque no hay colisión con su
identificación de seis caracteres ahora, esa condición puede cambiar dentro
de cinco años.
Si las discusiones relacionadas o cualquier otra información relativa al
cambio se pueden encontrar en la web, agregue las etiquetas 'Link:' que
apunten a estos. En caso de que su parche corrija un error, por poner un
ejemplo, agregue una etiqueta con una URL que haga referencia al informe en
los archivos de las listas de correo o un rastreador de errores; si el
parche es el resultado de alguna discusión anterior de la lista de correo o
algo documentado en la web, referencie esto.
Cuando se vincule a archivos de listas de correo, preferiblemente use el
servicio de archivador de mensajes lore.kernel.org. Para crear la URL del
enlace, utilice el contenido del encabezado ("header") ``Message-ID`` del
mensaje sin los corchetes angulares que lo rodean.
Por ejemplo::
Link: https://lore.kernel.org/30th.anniversary.repost@klaava.Helsinki.FI
Verifique el enlace para asegurarse de que realmente funciona y apunta al
mensaje correspondiente.
Sin embargo, intente que su explicación sea comprensible sin recursos
externos. Además de dar una URL a un archivo o error de la lista de correo,
resuma los puntos relevantes de la discusión que condujeron al parche tal y
como se envió.
Si su parche corrige un error en un commit específico, por ejemplo
encontró un problema usando ``git bisect``, utilice la etiqueta 'Fixes:'
con los primeros 12 caracteres del ID SHA-1 y el resumen de una línea. No
divida la etiqueta en varias líneas, las etiquetas están exentas de la
regla "ajustar a 75 columnas" para simplificar análisis de scripts. Por
ejemplo::
Fixes: 54a4f0239f2e ("KVM: MMU: hacer que kvm_mmu_zap_page()
devuelva la cantidad de páginas que realmente liberó")
Las siguientes configuraciones de ``git config`` se pueden usar para
agregar un bonito formato y generar este estilo con los comandos
``git log`` o ``git show``::
[core]
abbrev = 12
[pretty]
fixes = Fixes: %h (\"%s\")
Un ejemplo de uso::
$ git log -1 --pretty=fixes 54a4f0239f2e
Fixes: 54a4f0239f2e ("KVM: MMU: hacer que kvm_mmu_zap_page() devuelva la cantidad de páginas que realmente liberó")
.. _sp_split_changes:
Separe sus cambios
-------------------
Separe cada **cambio lógico** en un parche separado.
Por ejemplo, si sus cambios incluyen correcciones de errores y mejoras en
el rendimiento de un controlador, separe esos cambios en dos o más parches.
Si sus cambios incluyen una actualización de la API y una nueva controlador
que usa esta nueva API, sepárelos en dos parches.
Por otro lado, si realiza un solo cambio en numerosos archivos, agrupe esos
cambios en un solo parche. Por lo tanto, un solo cambio lógico estará
contenido en un solo parche.
El punto a recordar es que cada parche debe realizar un cambio que puede
ser verificado por los revisores fácilmente. Cada parche debe ser
justificable por sus propios méritos.
Si un parche depende de otro parche para que un cambio sea completo, eso
está bien. Simplemente incluya que **"este parche depende del parche X"**
en la descripción de su parche.
Cuando divida su cambio en una serie de parches, tenga especial cuidado en
asegurarse de que el kernel se compila y ejecuta correctamente después de
cada parche en la serie. Los desarrolladores que usan ``git bisect``
para rastrear un problema pueden terminar dividiendo su serie de parches en
cualquier punto; no le agradecerán si introdujo errores a la mitad.
Si no puede condensar su conjunto de parches en un conjunto más pequeño de
parches, solo publique, más o menos 15 a la vez, y espere la revisión e
integración.
Revise el estilo en sus cambios
--------------------------------
Revise su parche para ver si hay violaciones de estilo básico, cuyos
detalles pueden ser encontrados en Documentation/process/coding-style.rst.
No hacerlo simplemente desperdicia el tiempo de los revisores y su parche
será rechazado, probablemente sin siquiera ser leído.
Una excepción importante es cuando se mueve código de un archivo a otro.
En tal caso, en absoluto debe modificar el código movido en el mismo parche
en que lo mueve. Esto divide claramente el acto de mover el código y sus
cambios. Esto ayuda mucho a la revisión de la diferencias reales y permite
que las herramientas rastreen mejor el historial del código en sí.
Verifique sus parches con el verificador de estilo de parches antes de
enviarlos (scripts/checkpatch.pl). Tenga en cuenta, sin embargo, que el
verificador de estilo debe ser visto como una guía, no como un reemplazo
del juicio humano. Si su código es mejor con una violación entonces
probablemente sea mejor dejarlo estar.
El verificador informa a tres niveles:
- ERROR: cosas que es muy probable que estén mal
- WARNING: Advertencia. Cosas que requieren una revisión cuidadosa
- CHECK: Revisar. Cosas que requieren pensarlo
Debe poder justificar todas las violaciones que permanezcan en su parche.
Seleccione los destinatarios de su parche
------------------------------------------
Siempre debe incluir en copia a los apropiados maintainers del subsistema
en cualquier parche con código que mantengan; revise a través del archivo
MAINTAINERS y el historial de revisión del código fuente para ver quiénes
son esos maintainers. El script scripts/get_maintainer.pl puede ser muy
útil en este paso (pase rutas a sus parches como argumentos para
scripts/get_maintainer.pl). Si no puede encontrar un maintainer del
subsistema en el que está trabajando, Andrew Morton
(akpm@linux-foundation.org) sirve como maintainer de último recurso.
Normalmente, también debe elegir al menos una lista de correo para recibir
una copia de su conjunto de parches. linux-kernel@vger.kernel.org debe
usarse de forma predeterminada para todos los parches, pero el volumen en
esta lista ha hecho que muchos desarrolladores se desconecten. Busque en el
archivo MAINTAINERS una lista específica de los subsistemas; su parche
probablemente recibirá más atención allí. Sin embargo, no envíe spam a
listas no relacionadas.
Muchas listas relacionadas con el kernel están alojadas en kernel.org;
puedes encontrar un listado de estas en
https://subspace.kernel.org. Existen listas relacionadas con el kernel
alojadas en otros lugares, no obstante.
¡No envíe más de 15 parches a la vez a las listas de correo de vger!
Linus Torvalds es el árbitro final de todos los cambios aceptados en el
kernel de Linux. Su dirección de correo electrónico es
<torvalds@linux-foundation.org>. Recibe muchos correos electrónicos y, en
este momento, muy pocos parches pasan por Linus directamente, por lo que
normalmente debe hacer todo lo posible para -evitar- enviarle un correo
electrónico.
Si tiene un parche que corrige un error de seguridad explotable, envíe ese
parche a security@kernel.org. Para errores graves, se debe mantener un
poco de discreción y permitir que los distribuidores entreguen el parche a
los usuarios; en esos casos, obviamente, el parche no debe enviarse a
ninguna lista pública. Revise también
Documentation/process/security-bugs.rst.
Los parches que corrigen un error grave en un kernel en uso deben dirigirse
hacia los maintainers estables poniendo una línea como esta::
CC: stable@vger.kernel.org
en el área de sign-off de su parche (es decir, NO un destinatario de correo
electrónico). También debe leer
Documentation/process/stable-kernel-rules.rst además de este documento.
Si los cambios afectan las interfaces del kernel para el usuario, envíe al
maintainer de las MAN-PAGES (como se indica en el archivo MAINTAINERS) un
parche de páginas de manual, o al menos una notificación del cambio, para
que alguna información se abra paso en las páginas del manual. Los cambios
de la API del espacio de usuario también deben copiarse en
linux-api@vger.kernel.org.
Sin MIME, enlaces, compresión o archivos adjuntos. Solo texto plano
--------------------------------------------------------------------
Linus y otros desarrolladores del kernel deben poder leer y comentar sobre
los cambios que está enviando. Es importante para un desarrollador kernel
poder "citar" sus cambios, utilizando herramientas estándar de correo
electrónico, de modo que puedan comentar sobre partes específicas de su
código.
Por este motivo, todos los parches deben enviarse por correo electrónico
"inline". La forma más sencilla de hacerlo es con ``git send-email``, que
es muy recomendable. Un tutorial interactivo para ``git send-email`` está
disponible en https://git-send-email.io.
Si elige no usar ``git send-email``:
.. warning::
Tenga cuidado con el ajuste de palabras de su editor que corrompe su
parche, si elige cortar y pegar su parche.
No adjunte el parche como un archivo adjunto MIME, comprimido o no. Muchas
populares aplicaciones de correo electrónico no siempre transmiten un MIME
archivo adjunto como texto sin formato, por lo que es imposible comentar
en su código. Linus también necesita un poco más de tiempo para procesar un
archivo adjunto MIME, disminuyendo la probabilidad de que se acepte su
cambio adjunto en MIME.
Excepción: si su proveedor de correo está destrozando parches, entonces
alguien puede pedir que los vuelva a enviar usando MIME.
Consulte Documentation/process/email-clients.rst para obtener sugerencias
sobre cómo configurar su cliente de correo electrónico para que envíe sus
parches intactos.
Responda a los comentarios de revisión
---------------------------------------
Es casi seguro que su parche recibirá comentarios de los revisores sobre
maneras en que se pueda mejorar el parche, en forma de respuesta a su
correo electrónico. Debe responder a esos comentarios; ignorar a los
revisores es una buena manera de ser ignorado de vuelta. Simplemente puede
responder a sus correos electrónicos para contestar a sus comentarios.
Revisiones a los comentarios o preguntas que no conduzcan a un cambio de
código deben casi con certeza generar un comentario o una entrada en el
"changelog" para que el próximo revisor entienda lo que está pasando.
Asegúrese de decirles a los revisores qué cambios está haciendo y de
agradecerles que dediquen su tiempo. La revisión del código es un proceso
agotador y lento, y los revisores a veces se ponen de mal humor. Sin
embargo, incluso en ese caso, responda cortésmente y aborde los problemas
que hayan señalado. Al enviar un siguiente versión, agregue un
``patch changelog`` (registro de cambios en los parches) a la carta de
presentación ("cover letter") o a parches individuales explicando la
diferencia con la presentación anterior (ver
:ref:`sp_the_canonical_patch_format`).
Consulte Documentation/process/email-clients.rst para obtener
recomendaciones sobre clientes de correo electrónico y normas de etiqueta
en la lista de correo.
.. _sp_interleaved_replies:
Uso de respuestas intercaladas recortadas en las discusiones por correo electrónico
-----------------------------------------------------------------------------------
Se desaconseja encarecidamente la publicación en la parte superior de las
discusiones sobre el desarrollo del kernel de Linux. Las respuestas
intercaladas (o "en línea") hacen que las conversaciones sean mucho más
fáciles de seguir. Para obtener más detalles, consulte:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
Como se cita frecuentemente en la lista de correo::
A: http://en.wikipedia.org/wiki/Top_post
Q: ¿Dónde puedo encontrar información sobre esto que se llama top-posting?
A: Porque desordena el orden en el que la gente normalmente lee el texto.
Q: ¿Por qué es tan malo el top-posting?
A: Top-posting.
Q: ¿Qué es lo más molesto del correo electrónico?
Del mismo modo, por favor, recorte todas las citas innecesarias que no
sean relevantes para su respuesta. Esto hace que las respuestas sean más
fáciles de encontrar y ahorra tiempo y espacio. Para obtener más
información, consulte: http://daringfireball.net/2007/07/on_top ::
A: No.
Q: ¿Debo incluir citas después de mi respuesta?
.. _sp_resend_reminders:
No se desanime o impaciente
---------------------------
Después de haber entregado su cambio, sea paciente y espere. Los revisores
son personas ocupadas y es posible que no lleguen a su parche de inmediato.
Érase una vez, los parches solían desaparecer en el vacío sin comentarios,
pero el proceso de desarrollo funciona mejor que eso ahora. Debería
recibir comentarios dentro de una semana más o menos; si eso no sucede,
asegúrese de que ha enviado sus parches al lugar correcto. Espere un mínimo
de una semana antes de volver a enviar o hacer ping a los revisores,
posiblemente más durante periodos de mucho trabajo ocupados como "merge
windows".
También está bien volver a enviar el parche o la serie de parches después
de un par de semanas con la palabra "RESEND" (reenviar) añadida a la línea
de asunto::
[PATCH Vx RESEND] sub/sys: Resumen condensado de parche
No incluya "RESEND" cuando envíe una versión modificada de su parche o
serie de parches: "RESEND" solo se aplica al reenvío de un parche o serie
de parches que no hayan sido modificados de ninguna manera con respecto a
la presentación anterior.
Incluya PATCH en el asunto
--------------------------
Debido al alto tráfico de correo electrónico a Linus y al kernel de Linux,
es común prefijar su línea de asunto con [PATCH]. Esto le permite a Linus
y otros desarrolladores del kernel distinguir más fácilmente los parches de
otras discusiones por correo electrónico.
``git send-email`` lo hará automáticamente.
Firme su trabajo: el Certificado de Origen del Desarrollador
------------------------------------------------------------
Para mejorar el seguimiento de quién hizo qué, especialmente con parches
que pueden filtrarse hasta su destino final a través de varias capas de
maintainers, hemos introducido un procedimiento de "sign-off" (aprobación)
en parches que se envían por correo electrónico.
La aprobación es una simple línea al final de la explicación del parche,
que certifica que usted lo escribió o que tiene derecho a enviarlo como un
parche de código abierto. Las reglas son bastante simples: si usted puede
certificar lo siguiente:
Certificado de Origen del Desarrollador 1.1
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Al hacer una contribución a este proyecto, certifico que:
(a) La contribución fue creada en su totalidad o en parte por mí y
tengo derecho a enviarlo bajo la licencia de código abierto
indicada en el documento; o
(b) La contribución se basa en trabajo previo que, hasta donde yo
soy consciente, está cubierto por una licencia de código
abierto apropiada y tengo el derecho bajo esa licencia de
presentar tal trabajo con modificaciones, ya sean creadas en su
totalidad o en parte por mí, bajo la misma licencia de código
(salvo que sea permitido presentar bajo una licencia diferente),
tal y como se indica en el documento; o
(c) La contribución me fue proporcionada directamente por alguna
otra persona que certificó (a), (b) o (c) y no he modificado
esto.
(d) Entiendo y acepto que este proyecto y la contribución
son públicos y que un registro de la contribución (incluyendo
toda la información personal que envío con él, incluida mi
firma) es mantenida indefinidamente y puede ser redistribuida
de manera consistente con este proyecto o la(s) licencia(s) de
código abierto involucradas.
entonces simplemente incluya una línea que rece::
Signed-off-by: Random J Developer <random@developer.example.org>
usando su nombre real (lamentablemente, no pseudónimos ni contribuciones
anónimas). Esto se hará por usted automáticamente si usa ``git commit -s``.
Las reversiones de código también deben incluir "Signed-off-by".
``git revert -s`` hace eso por usted.
Algunas personas también ponen etiquetas adicionales al final. Simplemente
serán ignoradas por ahora, pero puede hacer esto para marcar procedimientos
internos de su empresa o simplemente señalar algún detalle especial sobre
la firma.
Cualquier otro SoB (Signed-off-by:) después del SoB del autor es de
personas que manipulen y transporten el parche, pero no participaron en su
desarrollo. Las cadenas de SoB deben reflejar la ruta **real** del parche
de cómo se propagó a los maintainers y, en última instancia, a Linus, con
la primera entrada de SoB que señala la autoría principal de un solo autor.
Cuándo usar Acked-by:, Cc: y Co-developed-by por:
-------------------------------------------------
La etiqueta Signed-off-by: indica que el firmante estuvo involucrado en el
desarrollo del parche, o que él/ella se encontraba en el camino de entrega
del parche.
Si una persona no estuvo directamente involucrada en la preparación o
administración de un parche pero desea expresar y registrar su aprobación,
entonces puede pedir que se agregue una línea Acked-by: al registro de
cambios del parche.
Acked-by: a menudo lo usa el maintainer del código afectado cuando ese
maintainer no contribuyó ni envió el parche.
Acked-by: no es tan formal como Signed-off-by:. Es una manera de marcar que
el "acker" ha revisado al menos ese parche y ha indicado su aceptación. Por
los merge de parches a veces convertirán manualmente el "sí, me parece bien"
de un acker en un Acked-by: (pero tenga en cuenta que por lo general es
mejor pedir un acuse de recibo explícito).
Acked-by: no necesariamente indica el reconocimiento de todo el parche.
Por ejemplo, si un parche afecta a varios subsistemas y tiene un
Acked-by: de un maintainer del subsistema, entonces esto generalmente
indica el reconocimiento de solo la parte que afecta el código de ese
maintainer. Buen juicio debe ejercitarse aquí. En caso de duda, la gente
debe consultar la discusión original en los archivos de la lista de correo.
Si una persona ha tenido la oportunidad de comentar un parche, pero no lo
ha hecho, puede incluir opcionalmente una etiqueta ``Cc:`` al parche.
Esta es la única etiqueta que se puede agregar sin una acción explícita por
parte de la persona a la que se nombre - pero debe indicar que esta persona
fue copiada en el parche. Esta etiqueta documenta que las partes
potencialmente interesadas han sido incluidas en la discusión.
Co-developed-by: establece que el parche fue co-creado por múltiples
desarrolladores; se utiliza para dar atribución a los coautores (además del
autor atribuido por la etiqueta From:) cuando varias personas trabajan en
un solo parche. Ya que Co-developed-by: denota autoría, cada
Co-developed-by: debe ser inmediatamente seguido de Signed-off-by: del
coautor asociado. Se mantiene el procedimiento estándar, es decir, el orden
de las etiquetas Signed-off-by: debe reflejar el historial cronológico del
parche en la medida de lo posible, independientemente de si el autor se
atribuye a través de From: o Co-developed-by:. Cabe destacar que el último
Signed-off-by: siempre debe ser del desarrollador que envía el parche.
Tenga en cuenta que la etiqueta From: es opcional cuando el autor From: es
también la persona (y correo electrónico) enumerados en la línea From: del
encabezado del correo electrónico.
Ejemplo de un parche enviado por el From: autor::
<changelog>
Co-developed-by: Primer coautor <primer@coauthor.example.org>
Signed-off-by: Primer coautor <primer@coauthor.example.org>
Co-developed-by: Segundo coautor <segundo@coautor.ejemplo.org>
Signed-off-by: Segundo coautor <segundo@coautor.ejemplo.org>
Signed-off-by: Autor del From <from@author.example.org>
Ejemplo de un parche enviado por un Co-developed-by: autor::
From: Autor del From <from@author.example.org>
<changelog>
Co-developed-by: Co-Autor aleatorio <aleatorio@coauthor.example.org>
Signed-off-by: Coautor aleatorio <aleatorio@coauthor.example.org>
Signed-off-by: Autor del From <from@author.example.org>
Co-developed-by: Coautor que envió <sub@coauthor.example.org>
Signed-off-by: Coautor que envía <sub@coauthor.example.org>
Uso de Reported-by:, Tested-by:, Reviewed-by:, Suggested-by: y Fixes:
----------------------------------------------------------------------
La etiqueta Reported-by (Reportado-por) otorga crédito a las personas que
encuentran errores y los reportan. Por favor, tenga en cuenta que si se
informó de un error en privado, debe pedir primero permiso antes de usar la
etiqueta Reported-by. La etiqueta está destinada a errores; por favor no la
use para acreditar peticiones de características.
Una etiqueta Tested-by: indica que el parche se probó con éxito (en algún
entorno) por la persona nombrada. Esta etiqueta informa a los maintainers
de que se han realizado algunas pruebas, proporciona un medio para ubicar
"testers" (gente que pruebe) otros parches futuros y asegura el crédito
para los testers.
Reviewed-by: en cambio, indica que el parche ha sido revisado y encontrado
aceptable de acuerdo con la Declaración del Revisor:
Declaración de Supervisión del Revisor
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Al ofrecer mi etiqueta Reviewed-by:, afirmo que:
(a) He llevado a cabo una revisión técnica de este parche para
evaluar su idoneidad y preparación para su inclusión en
el kernel principal.
(b) Cualquier problema, inquietud o pregunta relacionada con el parche
han sido comunicados al remitente. Estoy satisfecho
con la respuesta del remitente a mis comentarios.
(c) Si bien puede haber cosas que podrían mejorarse con esta
entrega, creo que es, en este momento, (1) una
modificación valiosa al kernel, y (2) libre de conocidas
cuestiones que argumentarían en contra de su inclusión.
(d) Si bien he revisado el parche y creo que es correcto,
no hago (a menos que se indique explícitamente en otro lugar) ninguna
garantía o avales de que logrará su definido
propósito o función en cualquier situación dada.
Una etiqueta Reviewed-by es una declaración de opinión de que el parche es
una modificación apropiada al kernel sin que haya ningún problema grave
a nivel técnico. Cualquier revisor interesado (que haya hecho el trabajo)
puede ofrecer una etiqueta Reviewed-by para un parche. Esta etiqueta sirve
para dar crédito a revisores e informar a los maintainers del grado de
revisión que se ha hecho en el parche. Las etiquetas Reviewed-by, cuando
las otorgan revisores conocidos por entender del tema y realizar
revisiones exhaustivas, normalmente aumentan la probabilidad de que su
parche entre en el kernel.
Las etiquetas Tested-by y Reviewed-by, una vez recibidas en la lista de
correo por el tester o revisor, deben ser incluidas por el autor de los
parches pertinentes al enviar próximas versiones. Sin embargo, si el parche
ha cambiado sustancialmente en la siguiente versión, es posible que estas
etiquetas ya no sean aplicables y, por lo tanto, deben eliminarse. Por lo
general, se debe mencionar la eliminación de las etiquetas Tested-by o
Reviewed-by de alguien en el registro de cambios del parche (después del
separador '---').
Una etiqueta Suggested-by: indica que la idea del parche es sugerida por la
persona nombrada y asegura el crédito a la persona por la idea. Tenga en
cuenta que esto no debe agregarse sin el permiso del "reporter",
especialmente si la idea no fue publicada en un foro público. Dicho esto,
si diligentemente acreditamos a los reporters de ideas, con suerte, se
sentirán inspirados para ayudarnos nuevamente en el futuro.
Una etiqueta Fixes: indica que el parche corrige un problema en un commit
anterior. Esto se utiliza para facilitar descubrir dónde se originó un
error, lo que puede ayudar a revisar una corrección de errores. Esta
etiqueta también ayuda al equipo del kernel estable a determinar qué
versiones estables del kernel deberían recibir su corrección. Este es el
método preferido para indicar un error corregido por el parche. Revise
:ref:`describe_changes` para más detalles.
Nota: Adjuntar una etiqueta Fixes: no subvierte las reglas estables del
proceso del kernel ni el requisito de CC: stable@vger.kernel.org en todos
los parches candidatos de ramas estables. Para obtener más información, lea
Documentation/process/stable-kernel-rules.rst.
.. _sp_the_canonical_patch_format:
Formato de parche canónico
---------------------------
Esta sección describe cómo debe darse formato al propio parche. Tenga en
cuenta que, si tiene sus parches almacenados en un repositorio ``git``, el
parche con formato adecuado se puede obtener con ``git format-patch``. Las
herramientas no pueden crear el texto necesario, sin embargo, así que lea
las instrucciones a continuación de todos modos.
La línea de asunto del parche canónico es::
Asunto: [PATCH 001/123] subsistema: frase de resumen
El cuerpo del mensaje del parche canónico contiene lo siguiente:
- Una línea ``from`` que especifica el autor del parche, seguida de una
línea vacía (solo es necesario si la persona que envía el parche no es
el autor).
- El cuerpo de la explicación, línea envuelta en 75 columnas, que se
copiara en el registro de cambios permanente para describir este parche.
- Una línea vacía.
- Las líneas ``Signed-off-by:``, descritas anteriormente, que
también vaya en el registro de cambios.
- Una línea de marcador que contiene simplemente ``---``.
- Cualquier comentario adicional que no sea adecuado para el registro de
cambios.
- El parche real (output de ``diff``).
El formato de la línea de asunto hace que sea muy fácil ordenar los correos
electrónicos alfabéticamente por línea de asunto - prácticamente cualquier
lector de correo electrónico permite esto, ya que debido a que el número de
secuencia se rellena con ceros, el orden numérico y alfabético es el mismo.
El ``subsistema`` en el asunto del correo electrónico debe identificar qué
área o subsistema del kernel está siendo parcheado.
La ``frase de resumen`` en el Asunto del correo electrónico debe describir
de forma concisa el parche que contiene ese correo electrónico. La
``frase resumen`` no debe ser un nombre de archivo. No use la mismo ``frase
resumen`` para cada parche en una serie completa de parches (donde una
`` serie de parches`` (patch series) es una secuencia ordenada de múltiples
parches relacionados).
Tenga en cuenta que la ``frase de resumen`` de su correo electrónico se
convierte en un identificador global único para ese parche. Se propaga por
hasta el registro de cambios de ``git``. La ``frase resumida`` se puede
usar más adelante en discusiones de desarrolladores que se refieran al
parche. La gente querrá buscar en Google la ``frase de resumen`` para leer
la discusión al respecto del parche. También será lo único que la gente
podrá ver rápidamente cuando, dos o tres meses después, estén pasando por
quizás miles de parches usando herramientas como ``gitk`` o ``git log
--oneline``.
Por estas razones, el ``resumen`` no debe tener más de 70-75 caracteres, y
debe describir tanto lo que cambia el parche como por qué el parche podría
ser necesario. Es un reto ser tanto sucinto como descriptivo, pero eso es
lo que un resumen bien escrito debería hacer.
La ``frase de resumen`` puede estar precedida por etiquetas encerradas en
corchetes: "Asunto: [PATCH <etiqueta>...] <frase de resumen>". Las
etiquetas no se consideran parte de la frase de resumen, pero describen
cómo debería ser tratado el parche. Las etiquetas comunes pueden incluir un
descriptor de versión si las múltiples versiones del parche se han enviado
en respuesta a comentarios (es decir, "v1, v2, v3") o "RFC" para indicar
una solicitud de comentarios.
Si hay cuatro parches en una serie de parches, los parches individuales
pueden enumerarse así: 1/4, 2/4, 3/4, 4/4. Esto asegura que los
desarrolladores entiendan el orden en que se deben aplicar los parches y
que han revisado o aplicado todos los parches de la serie de parches.
Aquí hay algunos buenos ejemplos de Asuntos::
Asunto: [PATCH 2/5] ext2: mejorar la escalabilidad de la búsqueda de mapas de bits
Asunto: [PATCH v2 27/01] x86: corregir el seguimiento de eflags
Asunto: [PATCH v2] sub/sys: resumen conciso del parche
Asunto: [PATCH v2 M/N] sub/sys: resumen conciso del parche
La línea ``from`` debe ser la primera línea en el cuerpo del mensaje,
y tiene la forma::
From: Autor del parche <autor@ejemplo.com>
La línea ``From`` especifica quién será acreditado como el autor del parche
en el registro de cambios permanente. Si falta la línea ``from``, entonces
la línea ``From:`` del encabezado del correo electrónico se usará para
determinar el autor del parche en el registro de cambios.
La explicación estará incluida en el commit del changelog permanente, por
lo que debería tener sentido para un lector competente que hace mucho tiempo
ha olvidado los detalles de la discusión que podrían haber llevado a
este parche. Incluidos los síntomas del fallo que el parche trate
(mensajes de registro del kernel, mensajes de oops, etc.) son especialmente
útiles para personas que podrían estar buscando en los registros de
commits en busca de la aplicación del parche. El texto debe estar escrito
con tal detalle que cuando se lea semanas, meses o incluso años después,
pueda dar al lector la información necesaria y detalles para comprender el
razonamiento de **por qué** se creó el parche.
Si un parche corrige una falla de compilación, puede que no sea necesario
incluir _todos_ los errores de compilación; pero lo suficiente como para
que sea probable que alguien que busque el parche puede encontrarlo. Como
en la ``frase de resumen``, es importante ser tanto sucinto como
descriptivo.
La línea marcadora ``---`` cumple el propósito esencial de marcar para
herramientas de manejo de parches donde termina el mensaje de registro de
cambios.
Un buen uso de los comentarios adicionales después del marcador ``---`` es
para ``diffstat``, para mostrar qué archivos han cambiado, y el número de
líneas insertadas y eliminadas por archivo. Un ``diffstat`` es
especialmente útil en parches más grandes. Si va a incluir un ``diffstat``
después del marcador ``---``, utilice las opciones ``diffstat``
``-p 1 -w 70`` para que los nombres de archivo se enumeran desde la parte
superior del árbol de fuentes del kernel y no use demasiado espacio
horizontal (que encaje fácilmente en 80 columnas, tal vez con alguna
indentación). (``git`` genera diffstats apropiados por defecto).
Otros comentarios relevantes solo en el momento o para el maintainer, pero
no adecuados para el registro de cambios permanente, también debe ir aquí.
Un buen ejemplo de tales comentarios podría ser ``registros de cambios de
parches`` que describen qué ha cambiado entre la versión v1 y v2 del
parche.
Por favor, ponga esta información **después** de la línea ``---`` que
separa el registro de cambios del resto del parche. La información de la
versión no forma parte del registro de cambios que se incluye con el árbol
git. Es información adicional para los revisores. Si se coloca encima de la
etiquetas de commit, necesita interacción manual para eliminarlo. Si esta
debajo de la línea de separación, se quita automáticamente al aplicar el
parche::
<mensaje de commit>
...
Signed-off-by: Autor <autor@correo>
---
V2 -> V3: función auxiliar redundante eliminada
V1 -> V2: estilo de código limpio y comentarios de revisión abordados
ruta/al/archivo | 5+++--
...
Revise más detalles sobre el formato de parche adecuado en las siguientes
referencias
.. _sp_backtraces:
Retrocesos en mensajes de confirmación
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Los "backtraces" (deshacer el camino) ayuda a documentar la cadena de
llamadas que conducen a un problema. Sin embargo, no todos los rastreos son
útiles. Por ejemplo, las tempranas cadenas de llamadas de inicio son únicas
y obvias. Sin embargo, al copiar la salida completa de dmesg textualmente,
incluye información que distrae, como marcas de tiempo, listas de módulos,
registro y volcados de pila.
Por lo tanto, los backtraces más útiles deben contener los datos
relevantes de la información vertida, lo que hace que sea más fácil
centrarse en el verdadero tema. Este es un ejemplo de un backtrace bien
recortado::
error de acceso de MSR no verificado: WRMSR a 0xd51 (intentó escribir 0x0000000000000064)
en rIP: 0xffffffffae059994 (native_write_msr+0x4/0x20)
Rastreo de llamadas:
mba_wrmsr
update_domains
rdtgroup_mkdir
.. _sp_explicit_in_reply_to:
In-Reply-To explicitos en las cabeceras
---------------------------------------
Puede ser útil agregar manualmente encabezados In-Reply-To: a un parche
(por ejemplo, al usar ``git send-email``) para asociar el parche con una
discusión anterior relevante, por ejemplo para vincular una corrección de
errores al correo electrónico con el informe de errores. Sin embargo, para
una serie de parches múltiples, generalmente es mejor evitar usar
In-Reply-To: para vincular a versiones anteriores de la serie. De esta
forma, varias versiones del parche no se convierten en un inmanejable
bosque de referencias en clientes de correo electrónico. Si un enlace es
útil, puede usar el redirector https://lore.kernel.org/ (por ejemplo, en
el texto de la carta de introducción del correo electrónico) para vincular
a una versión anterior de la serie de parches.
Proporcionar información de árbol base
--------------------------------------
Cuando otros desarrolladores reciben sus parches y comienzan el proceso de
revisión, a menudo es útil para ellos saber en qué parte del historial del
árbol deben colocar su trabajo. Esto es particularmente útil para CI
automatizado de procesos que intentan ejecutar una serie de pruebas para
establecer la calidad de su envío antes de que el maintainer comience la
revisión.
Si está utilizando ``git format-patch`` para generar sus parches, puede
incluir automáticamente la información del árbol base en su envío usando el
parámetro ``--base``. La forma más fácil y conveniente de usar esta opción
es con "topical branches" (ramas de temas)::
$ git checkout -t -b my-topical-branch master
Branch 'my-topical-branch' set up to track local branch 'master'.
Switched to a new branch 'my-topical-branch'
[realice sus cambios y ediciones]
$ git format-patch --base=auto --cover-letter -o outgoing/ master
outgoing/0000-cover-letter.patch
outgoing/0001-First-Commit.patch
outgoing/...
Cuando abra ``outgoing/0000-cover-letter.patch`` para editar, tenga en
cuenta que tendrá el tráiler ``base-commit:`` al final, que proporciona al
revisor y a las herramientas de CI suficiente información para realizar
correctamente ``git am`` sin preocuparse por los conflictos::
$ git checkout -b patch-review [base-commit-id]
Switched to a new branch 'patch-review'
$ git am patches.mbox
Applying: First Commit
Applying: ...
Consulte ``man git-format-patch`` para obtener más información al respecto
de esta opción.
.. Note::
La función ``--base`` se introdujo en la versión 2.9.0 de git.
Si no está utilizando git para dar forma a sus parches, aún puede incluir
el mismo tráiler ``base-commit`` para indicar el hash de confirmación del
árbol en que se basa su trabajo. Debe agregarlo en la carta de presentación
o en el primer parche de la serie y debe colocarse ya sea bajo la línea
``---`` o en la parte inferior de todos los demás contenido, justo antes de
su firma del correo electrónico.
Referencias
-----------
"The perfect patch" (tpp) por Andrew Morton.
<https://www.ozlabs.org/~akpm/stuff/tpp.txt>
"Linux kernel patch submission format" por Jeff Garzik.
<https://web.archive.org/web/20180829112450/http://linux.yyz.us/patch-format.html>
"How to piss off a kernel subsystem maintainer" por Greg Kroah-Hartman.
<http://www.kroah.com/log/linux/maintainer.html>
<http://www.kroah.com/log/linux/maintainer-02.html>
<http://www.kroah.com/log/linux/maintainer-03.html>
<http://www.kroah.com/log/linux/maintainer-04.html>
<http://www.kroah.com/log/linux/maintainer-05.html>
<http://www.kroah.com/log/linux/maintainer-06.html>
Kernel Documentation/process/coding-style.rst
Email de Linus Torvalds sobre la forma canónica de los parches:
<https://lore.kernel.org/r/Pine.LNX.4.58.0504071023190.28951@ppc970.osdl.org>
"On submitting kernel patches" por Andi Kleen
Algunas estrategias para conseguir incluir cambios complicados o
controvertidos.
http://halobates.de/on-submitting-patches.pdf