diff options
Diffstat (limited to 'Documentation/translations/sp_SP/process')
4 files changed, 2411 insertions, 0 deletions
diff --git a/Documentation/translations/sp_SP/process/coding-style.rst b/Documentation/translations/sp_SP/process/coding-style.rst new file mode 100644 index 000000000000..a0261ba5b902 --- /dev/null +++ b/Documentation/translations/sp_SP/process/coding-style.rst @@ -0,0 +1,1315 @@ +.. include:: ../disclaimer-sp.rst + +:Original: :ref:`Documentation/process/coding-style.rst <submittingpatches>` +:Translator: Carlos Bilbao <carlos.bilbao@amd.com> + +.. _sp_codingstyle: + +Estilo en el código del kernel Linux +===================================== + +Este es un breve documento que describe el estilo preferido en el código +del kernel Linux. El estilo de código es muy personal y no **forzaré** mi +puntos de vista sobre nadie, pero esto vale para todo lo que tengo que +mantener, y preferiría que para la mayoría de otras cosas también. Por +favor, por lo menos considere los argumentos expuestos aquí. + +En primer lugar, sugeriría imprimir una copia de los estándares de código +GNU, y NO leerlo. Quémelos, es un gran gesto simbólico. + +De todos modos, aquí va: + + +1) Sangría +----------- + +Las tabulaciones tienen 8 caracteres y, por lo tanto, las sangrías también +tienen 8 caracteres. Hay movimientos heréticos que intentan hacer sangría +de 4 (¡o incluso 2!) caracteres de longitud, y eso es similar a tratar de +definir el valor de PI como 3. + +Justificación: La idea detrás de la sangría es definir claramente dónde +comienza y termina un bloque de control. Especialmente, cuando ha estado +buscando en su pantalla durante 20 horas seguidas, le resultará mucho más +fácil ver cómo funciona la sangría si tiene sangrías grandes. + +Bueno, algunas personas dirán que tener sangrías de 8 caracteres hace que +el código se mueva demasiado a la derecha y dificulta la lectura en una +pantalla de terminal de 80 caracteres. La respuesta a eso es que si +necesita más de 3 niveles de sangría, está en apuros de todos modos y +debería arreglar su programa. + +En resumen, las sangrías de 8 caracteres facilitan la lectura y tienen la +ventaja añadida de advertirle cuando está anidando sus funciones demasiado +profundo. Preste atención a esa advertencia. + +La forma preferida de facilitar múltiples niveles de sangría en una +declaración de switch es para alinear el ``switch`` y sus etiquetas +``case`` subordinadas en la misma columna, en lugar de hacer ``doble +sangría`` (``double-indenting``) en etiquetas ``case``. Por ejemplo: + +.. code-block:: c + + switch (suffix) { + case 'G': + case 'g': + mem <<= 30; + break; + case 'M': + case 'm': + mem <<= 20; + break; + case 'K': + case 'k': + mem <<= 10; + fallthrough; + default: + break; + } + +No ponga varias declaraciones en una sola línea a menos que tenga algo que +ocultar: + +.. code-block:: c + + if (condición) haz_esto; + haz_otra_cosa; + +No use comas para evitar el uso de llaves: + +.. code-block:: c + + if (condición) + haz_esto(), haz_eso(); + +Siempre use llaves para múltiples declaraciones: + +.. code-block:: c + + if (condición) { + haz_esto(); + haz_eso(); + } + +Tampoco ponga varias asignaciones en una sola línea. El estilo de código +del kernel es súper simple. Evite las expresiones engañosas. + + +Aparte de los comentarios, la documentación y excepto en Kconfig, los +espacios nunca se utilizan para la sangría, y el ejemplo anterior se rompe +deliberadamente. + +Consiga un editor decente y no deje espacios en blanco al final de las +líneas. + +2) Rompiendo líneas y strings largos +------------------------------------ + +El estilo de código tiene todo que ver con la legibilidad y la +mantenibilidad usando herramientas disponibles comúnmente. + +El límite preferido en la longitud de una sola línea es de 80 columnas. + +Las declaraciones de más de 80 columnas deben dividirse en partes, a menos +que exceder las 80 columnas aumente significativamente la legibilidad y no +oculte información. + +Los descendientes siempre son sustancialmente más cortos que el padre y +se colocan sustancialmente a la derecha. Un estilo muy usado es alinear +descendientes a un paréntesis de función abierto. + +Estas mismas reglas se aplican a los encabezados de funciones con una larga +lista de argumentos. + +Sin embargo, nunca rompa los strings visibles para el usuario, como los +mensajes printk, porque eso rompe la capacidad de grep a estos. + + +3) Colocación de llaves y espacios +---------------------------------- + +El otro problema que siempre surge en el estilo C es la colocación de +llaves. A diferencia del tamaño de la sangría, existen pocas razones +técnicas para elegir una estrategia de ubicación sobre la otra, pero la +forma preferida, como mostraron los profetas Kernighan y Ritchie, es poner +la llave de apertura en la línea, y colocar la llave de cierre primero, +así: + +.. code-block:: c + + if (x es verdad) { + hacemos y + } + +Esto se aplica a todos los bloques de declaraciones que no son funciones +(if, switch, for, while, do). Por ejemplo: + +.. code-block:: c + + switch (action) { + case KOBJ_ADD: + return "add"; + case KOBJ_REMOVE: + return "remove"; + case KOBJ_CHANGE: + return "change"; + default: + return NULL; + } + +Sin embargo, hay un caso especial, a saber, las funciones: tienen la llave +de apertura al comienzo de la siguiente línea, así: + +.. code-block:: c + + int funcion(int x) + { + cuerpo de la función + } + +Gente hereje de todo el mundo ha afirmado que esta inconsistencia es... +bueno... inconsistente, pero todas las personas sensatas saben que +(a) K&R tienen **razón** y (b) K&R tienen razón. Además, las funciones son +especiales de todos modos (no puede anidarlas en C). + +Tenga en cuenta que la llave de cierre está vacía en su línea propia, +**excepto** en los casos en que es seguida por una continuación de la misma +declaración, es decir, un ``while`` en una sentencia do o un ``else`` en +una sentencia if, como en: + +.. code-block:: c + + do { + cuerpo del bucle do + } while (condition); + +y + +.. code-block:: c + + if (x == y) { + .. + } else if (x > y) { + ... + } else { + .... + } + +Justificación: K&R. + +Además, tenga en cuenta que esta colocación de llaves también minimiza el +número de líneas vacías (o casi vacías), sin pérdida de legibilidad. Así, +como el suministro de nuevas líneas en su pantalla no es un recurso +renovable (piense en pantallas de terminal de 25 líneas), tienes más líneas +vacías para poner comentarios. + +No use llaves innecesariamente donde una sola declaración sea suficiente. + +.. code-block:: c + + if (condition) + accion(); + +y + +.. code-block:: none + + if (condición) + haz_esto(); + else + haz_eso(); + +Esto no aplica si solo una rama de una declaración condicional es una sola +declaración; en este último caso utilice llaves en ambas ramas: + +.. code-block:: c + + if (condición) { + haz_esto(); + haz_eso(); + } else { + en_otro_caso(); + } + +Además, use llaves cuando un bucle contenga más de una declaración simple: + +.. code-block:: c + + while (condición) { + if (test) + haz_eso(); + } + +3.1) Espacios +************* + +El estilo del kernel Linux para el uso de espacios depende (principalmente) +del uso de función versus uso de palabra clave. Utilice un espacio después +de (la mayoría de) las palabras clave. Las excepciones notables son sizeof, +typeof, alignof y __attribute__, que parecen algo así como funciones (y +generalmente se usan con paréntesis en Linux, aunque no son requeridos en +el idioma, como en: ``sizeof info`` después de que ``struct fileinfo info;`` +se declare). + +Así que use un espacio después de estas palabras clave:: + + if, switch, case, for, do, while + +pero no con sizeof, typeof, alignof, o __attribute__. Por ejemplo, + +.. code-block:: c + + + s = sizeof(struct file); + +No agregue espacios alrededor (dentro) de expresiones entre paréntesis. +Este ejemplo es **malo**: + +.. code-block:: c + + + s = sizeof( struct file ); + +Al declarar datos de puntero o una función que devuelve un tipo de puntero, +el uso preferido de ``*`` es adyacente al nombre del dato o nombre de la +función y no junto al nombre del tipo. Ejemplos: + +.. code-block:: c + + + char *linux_banner; + unsigned long long memparse(char *ptr, char **retptr); + char *match_strdup(substring_t *s); + +Use un espacio alrededor (a cada lado de) la mayoría de los operadores +binarios y ternarios, como cualquiera de estos:: + + = + - < > * / % | & ^ <= >= == != ? : + +pero sin espacio después de los operadores unarios:: + + & * + - ~ ! sizeof typeof alignof __attribute__ defined + +sin espacio antes de los operadores unarios de incremento y decremento del +sufijo:: + + ++ -- + +y sin espacio alrededor de los operadores de miembros de estructura ``.`` y +``->``. + +No deje espacios en blanco al final de las líneas. Algunos editores con +``inteligente`` sangría insertarán espacios en blanco al comienzo de las +nuevas líneas como sea apropiado, para que pueda comenzar a escribir la +siguiente línea de código de inmediato. Sin embargo, algunos de estos +editores no eliminan los espacios en blanco si finalmente no termina +poniendo una línea de código allí, como si dejara una línea en blanco. Como +resultado, termina con líneas que contienen espacios en blanco al final. + +Git le advertirá sobre los parches que introducen espacios en blanco al +final y puede, opcionalmente, eliminar los espacios en blanco finales por +usted; sin embargo, si se aplica una serie de parches, esto puede hacer que +los parches posteriores de la serie fallen al cambiar sus líneas de +contexto. + + +4) Nomenclatura +--------------- + +C es un lenguaje espartano, y sus convenciones de nomenclatura deberían +seguir su ejemplo. A diferencia de los programadores de Modula-2 y Pascal, +los programadores de C no usan nombres cuquis como +EstaVariableEsUnContadorTemporal. Un programador de C lo llamaría +variable ``tmp``, que es mucho más fácil de escribir, y no es mas difícil +de comprender. + +SIN EMBARGO, mientras que los nombres de mayúsculas y minúsculas están mal +vistos, los nombres descriptivos para las variables globales son +imprescindibles. Llamar a una función global ``foo`` es un delito. + +Una variable GLOBAL (para usar solo si **realmente** las necesita) necesita +tener un nombre descriptivo, al igual que las funciones globales. Si tiene +una función que cuenta el número de usuarios activos, debe llamar a esta +``contar_usuarios_activos()`` o similar, **no** debe llamarlo ``cntusr()``. + +Codificar el tipo de una función en el nombre (lo llamado notación húngara) +es estúpido: el compilador conoce los tipos de todos modos y puede +verificar estos, y solo confunde al programador. + +Los nombres de las variables LOCALES deben ser breves y directos. Si usted +tiene algún contador aleatorio de tipo entero, probablemente debería +llamarse ``i``. Llamarlo ``loop_counter`` no es productivo, si no hay +posibilidad de ser mal entendido. De manera similar, ``tmp`` puede ser casi +cualquier tipo de variable que se utiliza para contener un valor temporal. + +Si tiene miedo de mezclar los nombres de las variables locales, tiene otro +problema, que se denomina síndrome de +función-crecimiento-desequilibrio-de-hormona. Vea el capítulo 6 (Funciones). + +Para nombres de símbolos y documentación, evite introducir nuevos usos de +'master / slave' (maestro / esclavo) (o 'slave' independientemente de +'master') y 'lista negra / lista blanca' (backlist / whitelist). + +Los reemplazos recomendados para 'maestro / esclavo' son: + '{primary,main} / {secondary,replica,subordinate}' + '{initiator,requester} / {target,responder}' + '{controller,host} / {device,worker,proxy}' + 'leader / follower' + 'director / performer' + +Los reemplazos recomendados para 'backlist / whitelist' son: + 'denylist / allowlist' + 'blocklist / passlist' + +Las excepciones para la introducción de nuevos usos son mantener en espacio +de usuario una ABI/API, o al actualizar la especificación del código de un +hardware o protocolo existente (a partir de 2020) que requiere esos +términos. Para nuevas especificaciones, traduzca el uso de la terminología +de la especificación al estándar de código del kernel donde sea posible. + +5) Typedefs +----------- + +Por favor no use cosas como ``vps_t``. +Es un **error** usar typedef para estructuras y punteros. cuando ve un + +.. code-block:: c + + + vps_t a; + +en el código fuente, ¿qué significa? +En cambio, si dice + +.. code-block:: c + + struct virtual_container *a; + +puede decir qué es ``a`` en realidad. + +Mucha gente piensa que los typedefs ``ayudan a la legibilidad``. No. Son +útiles solamente para: + + (a) objetos totalmente opacos (donde el typedef se usa activamente para + **ocultar** cuál es el objeto). + + Ejemplo: ``pte_t`` etc. objetos opacos a los que solo puede acceder + usando las funciones de acceso adecuadas. + + .. note:: + + La opacidad y las ``funciones de acceso`` no son buenas por sí + mismas. La razón por la que los tenemos para cosas como pte_t, etc. + es que hay real y absolutamente **cero** información accesible de + forma portátil allí. + + (b) Tipos enteros claros, donde la abstracción **ayuda** a evitar + confusiones, ya sea ``int`` o ``long``. + + u8/u16/u32 son definiciones tipográficas perfectamente correctas + aunque encajan en la categoría (d) mejor que aquí. + + .. note:: + + De nuevo - debe haber una **razón** para esto. si algo es + ``unsigned long``, entonces no hay razón para hacerlo + + typedef unsigned long mis_flags_t; + + pero si hay una razón clara de por qué bajo ciertas circunstancias + podría ser un ``unsigned int`` y bajo otras configuraciones podría + ser ``unsigned long``, entonces, sin duda, adelante y use un typedef. + + (c) cuando lo use para crear literalmente un tipo **nuevo** para + comprobación de tipos. + + (d) Nuevos tipos que son idénticos a los tipos estándar C99, en ciertas + circunstancias excepcionales. + + Aunque sólo costaría un corto período de tiempo para los ojos y + cerebro para acostumbrarse a los tipos estándar como ``uint32_t``, + algunas personas se oponen a su uso de todos modos. + + Por lo tanto, los tipos ``u8/u16/u32/u64`` específicos de Linux y sus + equivalentes con signo, que son idénticos a los tipos estándar son + permitidos, aunque no son obligatorios en el nuevo código de su + elección. + + Al editar código existente que ya usa uno u otro conjunto de tipos, + debe ajustarse a las opciones existentes en ese código. + + (e) Tipos seguros para usar en el espacio de usuario. + + En ciertas estructuras que son visibles para el espacio de usuario, no + podemos requerir tipos C99 y o utilizat el ``u32`` anterior. Por lo + tanto, usamos __u32 y tipos similares en todas las estructuras que se + comparten con espacio de usuario. + +Tal vez también haya otros casos, pero la regla básicamente debería ser +NUNCA JAMÁS use un typedef a menos que pueda coincidir claramente con una +de estas reglas. + +En general, un puntero o una estructura que tiene elementos que pueden +ser razonablemente accedidos directamente, **nunca** deben ser un typedef. + +6) Funciones +------------ + +Las funciones deben ser cortas y dulces, y hacer una sola cosa. Deberían +caber en una o dos pantallas de texto (el tamaño de pantalla ISO/ANSI es +80x24, como todos sabemos), y hacer una cosa y hacerla bien. + +La longitud máxima de una función es inversamente proporcional a la +complejidad y el nivel de sangría de esa función. Entonces, si tiene una +función conceptualmente simple que es solo una larga (pero simple) +declaración de case, donde tiene que hacer un montón de pequeñas cosas para +un montón de diferentes casos, está bien tener una función más larga. + +Sin embargo, si tiene una función compleja y sospecha que un estudiante de +primer año de secundaria menos que dotado podría no comprender de qué se +trata la función, debe adherirse a los límites máximos tanto más de +cerca. Use funciones auxiliares con nombres descriptivos (puede pedirle al +compilador que los alinee si cree que es crítico para el rendimiento, y +probablemente lo hará mejor de lo que usted hubiera hecho). + +Otra medida de la función es el número de variables locales. Estas no deben +exceder de 5 a 10, o está haciendo algo mal. Piense de nuevo en la función +y divida en partes más pequeñas. Un cerebro humano puede generalmente +realiza un seguimiento de aproximadamente 7 cosas diferentes, cualquier +elemento más y se confunde. Usted sabe que es brillante, pero tal vez le +gustaría entender lo que hizo dentro de 2 semanas. + +En los archivos fuente, separe las funciones con una línea en blanco. Si la +función es exportada, la macro **EXPORT** debería ponerse inmediatamente +después de la función de cierre de línea de llave. Por ejemplo: + +.. code-block:: c + + int sistema_corriendo(void) + { + return estado_sistema == SISTEMA_CORRIENDO; + } + EXPORT_SYMBOL(sistema_corriendo); + +6.1) Prototipos de funciones +**************************** + +En los prototipos de funciones, incluya nombres de parámetros con sus tipos +de datos. Aunque esto no es requerido por el lenguaje C, se prefiere en +Linux porque es una forma sencilla de añadir información valiosa para el +lector. + +No utilice la palabra clave ``extern`` con declaraciones de función ya que +esto hace las líneas más largas y no es estrictamente necesario. + +Al escribir prototipos de funciones, mantenga el `orden de los elementos regular +<https://lore.kernel.org/mm-commits/CAHk-=wiOCLRny5aifWNhr621kYrJwhfURsa0vFPeUEm8mF0ufg@mail.gmail.com/>`_. +Por ejemplo, usando este ejemplo de declaración de función:: + + __init void * __must_check action(enum magic value, size_t size, u8 count, + char *fmt, ...) __printf(4, 5) __malloc; + +El orden preferido de elementos para un prototipo de función es: + +- clase de almacenamiento (a continuación, ``static __always_inline``, + teniendo en cuenta que ``__always_inline`` es técnicamente un atributo + pero se trata como ``inline``) +- atributos de clase de almacenamiento (aquí, ``__init`` -- es decir, + declaraciones de sección, pero también cosas como ``__cold``) +- tipo de retorno (aquí, ``void *``) +- atributos de tipo de retorno (aquí, ``__must_check``) +- nombre de la función (aquí, ``action``) +- parámetros de la función (aquí, ``(enum magic value, size_t size, u8 count, char *fmt, ...)``, + teniendo en cuenta que los nombres de los parámetros siempre deben + incluirse) +- atributos de parámetros de función (aquí, ``__printf(4, 5)``) +- atributos de comportamiento de la función (aquí, ``__malloc``) + +Tenga en cuenta que para una **definición** de función (es decir, el cuerpo +real de la función), el compilador no permite atributos de parámetros de +función después de parámetros de la función. En estos casos, deberán ir +tras los atributos de clase (por ejemplo, tenga en cuenta el cambio de +posición de ``__printf(4, 5)`` a continuación, en comparación con el +ejemplo de **declaración** anterior):: + + static __always_inline __init __printf(4, 5) void * __must_check action(enum magic value, + size_t size, u8 count, char *fmt, ...) __malloc + { + ... + } + +7) Salida centralizada de funciones +----------------------------------- + +Aunque desaprobado por algunas personas, el equivalente de la instrucción +goto es utilizado con frecuencia por los compiladores, en forma de +instrucción de salto incondicional. + +La declaración goto es útil cuando una función sale desde múltiples +ubicaciones y se deben realizar algunos trabajos comunes, como la limpieza. +Si no se necesita limpieza, entonces simplemente haga return directamente. + +Elija nombres de etiquetas que digan qué hace el goto o por qué existe el +goto. Un ejemplo de un buen nombre podría ser ``out_free_buffer:`` +(``salida_liberar_buffer``) si al irse libera ``buffer``. Evite usar +nombres GW-BASIC como ``err1:`` y ``err2:``, ya que tendría que volver a +numerarlos si alguna vez agrega o elimina rutas de salida, y hacen que sea +difícil de verificar que sean correctos, de todos modos. + +La razón para usar gotos es: + +- Las declaraciones incondicionales son más fáciles de entender y seguir. +- se reduce el anidamiento +- errores al no actualizar los puntos de salida individuales al hacer + modificaciones son evitados +- ahorra el trabajo del compilador de optimizar código redundante ;) + +.. code-block:: c + + int fun(int a) + { + int result = 0; + char *buffer; + + buffer = kmalloc(SIZE, GFP_KERNEL); + if (!buffer) + return -ENOMEM; + + if (condition1) { + while (loop1) { + ... + } + result = 1; + goto out_free_buffer; + } + ... + out_free_buffer: + kfree(buffer); + return result; + } + +Un tipo común de error a tener en cuenta es "un error de error" que es algo +así: + +.. code-block:: c + + err: + kfree(foo->bar); + kfree(foo); + return ret; + +El error en este código es que en algunas rutas de salida, ``foo`` es NULL. +Normalmente la solución para esto es dividirlo en dos etiquetas de error +``err_free_bar:`` y ``err_free_foo:``: + +.. code-block:: c + + err_free_bar: + kfree(foo->bar); + err_free_foo: + kfree(foo); + return ret; + +Idealmente, debería simular errores para probar todas las rutas de salida. + + +8) Comentarios +-------------- + +Los comentarios son buenos, pero también existe el peligro de comentar +demasiado. NUNCA trate de explicar CÓMO funciona su código en un +comentario: es mucho mejor escribir el código para que el +**funcionamiento** sea obvio y es una pérdida de tiempo explicar código mal +escrito. + +Generalmente, desea que sus comentarios digan QUÉ hace su código, no CÓMO. +Además, trate de evitar poner comentarios dentro del cuerpo de una función: +si la función es tan compleja que necesita comentar por separado partes de +esta, probablemente debería volver al capítulo 6 una temporada. Puede +hacer pequeños comentarios para notar o advertir sobre algo particularmente +inteligente (o feo), pero trate de evitar el exceso. En su lugar, ponga los +comentarios al principio de la función, diga a la gente lo que hace y +posiblemente POR QUÉ hace esto. + +Al comentar las funciones de la API del kernel, utilice el formato +kernel-doc. Consulte los archivos en :ref:`Documentation/doc-guide/ <doc_guide>` +y ``scripts/kernel-doc`` para más detalles. + +El estilo preferido para comentarios largos (de varias líneas) es: + +.. code-block:: c + + /* + * Este es el estilo preferido para comentarios + * multilínea en el código fuente del kernel Linux. + * Por favor, utilícelo constantemente. + * + * Descripción: Una columna de asteriscos en el lado izquierdo, + * con líneas iniciales y finales casi en blanco. + */ + +Para archivos en net/ y drivers/net/, el estilo preferido para comentarios +largos (multi-linea) es un poco diferente. + +.. code-block:: c + + /* El estilo de comentario preferido para archivos en net/ y drivers/net + * se asemeja a esto. + * + * Es casi lo mismo que el estilo de comentario generalmente preferido, + * pero no hay una línea inicial casi en blanco. + */ + +También es importante comentar los datos, ya sean tipos básicos o +derivados. Para este fin, use solo una declaración de datos por línea (sin +comas para múltiples declaraciones de datos). Esto le deja espacio para un +pequeño comentario sobre cada elemento, explicando su uso. + +9) Has hecho un desastre +--------------------------- + +Está bien, todos lo hacemos. Probablemente un antiguo usuario de Unix le +haya dicho que ``GNU emacs`` formatea automáticamente las fuentes C por +usted, y ha notado que sí, lo hace, pero los por defecto que tiene son +menos que deseables (de hecho, son peores que los aleatorios) escribiendo - +un número infinito de monos escribiendo en GNU emacs nunca harán un buen +programa). + +Por lo tanto, puede deshacerse de GNU emacs o cambiarlo y usar valores más +sanos. Para hacer esto último, puede pegar lo siguiente en su archivo +.emacs: + +.. code-block:: none + + (defun c-lineup-arglist-tabs-only (ignored) + "Line up argument lists by tabs, not spaces" + (let* ((anchor (c-langelem-pos c-syntactic-element)) + (column (c-langelem-2nd-pos c-syntactic-element)) + (offset (- (1+ column) anchor)) + (steps (floor offset c-basic-offset))) + (* (max steps 1) + c-basic-offset))) + + (dir-locals-set-class-variables + 'linux-kernel + '((c-mode . ( + (c-basic-offset . 8) + (c-label-minimum-indentation . 0) + (c-offsets-alist . ( + (arglist-close . c-lineup-arglist-tabs-only) + (arglist-cont-nonempty . + (c-lineup-gcc-asm-reg c-lineup-arglist-tabs-only)) + (arglist-intro . +) + (brace-list-intro . +) + (c . c-lineup-C-comments) + (case-label . 0) + (comment-intro . c-lineup-comment) + (cpp-define-intro . +) + (cpp-macro . -1000) + (cpp-macro-cont . +) + (defun-block-intro . +) + (else-clause . 0) + (func-decl-cont . +) + (inclass . +) + (inher-cont . c-lineup-multi-inher) + (knr-argdecl-intro . 0) + (label . -1000) + (statement . 0) + (statement-block-intro . +) + (statement-case-intro . +) + (statement-cont . +) + (substatement . +) + )) + (indent-tabs-mode . t) + (show-trailing-whitespace . t) + )))) + + (dir-locals-set-directory-class + (expand-file-name "~/src/linux-trees") + 'linux-kernel) + +Esto hará que emacs funcione mejor con el estilo de código del kernel para +C en archivos bajo ``~/src/linux-trees``. + +Pero incluso si no logra que emacs realice un formateo correcto, no todo +está perdido: use ``indent``. + +Ahora bien, de nuevo, la sangría de GNU tiene la misma configuración de +muerte cerebral que GNU emacs tiene, por lo que necesita darle algunas +opciones de línea de comando. Sin embargo, eso no es tan malo, porque +incluso los creadores de GNU indent reconocen la autoridad de K&R (la gente +de GNU no es mala, solo están gravemente equivocados en este asunto), por +lo que simplemente de a la sangría las opciones ``-kr -i8`` (significa +``K&R, guiones de 8 caracteres``), o use ``scripts/Lindent``, que indenta +con ese estilo. + +``indent`` tiene muchas opciones, y especialmente cuando se trata de +comentar reformateos, es posible que desee echar un vistazo a la página del +manual. Pero recuerde: ``indent`` no es la solución para una mala +programación. + +Tenga en cuenta que también puede usar la herramienta ``clang-format`` para +ayudarlo con estas reglas, para volver a formatear rápidamente partes de su +código automáticamente, y revisar archivos completos para detectar errores +de estilo del código, errores tipográficos y posibles mejoras. También es +útil para ordenar ``#includes``, para alinear variables/macros, para +redistribuir texto y otras tareas similares. Vea el archivo +:ref:`Documentation/process/clang-format.rst <clangformat>` para más +detalles. + +10) Archivos de configuración de Kconfig +---------------------------------------- + +Para todos los archivos de configuración de Kconfig* en todo el árbol +fuente, la sangría es algo diferente. Las líneas bajo una definición +``config`` están indentadas con una tabulación, mientras que el texto de +ayuda tiene una sangría adicional de dos espacios. Ejemplo:: + + config AUDIT + bool "Soporte para auditar" + depends on NET + help + Habilita la infraestructura de auditoría que se puede usar con otro + subsistema kernel, como SELinux (que requiere esto para + registro de salida de mensajes avc). No hace auditoría de llamadas al + sistema sin CONFIG_AUDITSYSCALL. + +Características seriamente peligrosas (como soporte de escritura para +ciertos filesystems) deben anunciar esto de forma destacada en su cadena de +solicitud:: + + config ADFS_FS_RW + bool "ADFS write support (DANGEROUS)" + depends on ADFS_FS + ... + +Para obtener la documentación completa sobre los archivos de configuración, +consulte el archivo Documentation/kbuild/kconfig-language.rst. + + +11) Estructuras de datos +------------------------ + +Las estructuras de datos que tienen visibilidad fuera del contexto de un +solo subproceso en el que son creadas y destruidas, siempre debe tener +contadores de referencia. En el kernel, la recolección de basura no existe +(y fuera, la recolección de basura del kernel es lenta e ineficiente), lo +que significa que absolutamente **tiene** para hacer referencia y contar +todos sus usos. + +El conteo de referencias significa que puede evitar el bloqueo y permite +que múltiples usuarios tengan acceso a la estructura de datos en paralelo - +y no tengan que preocuparse de que la estructura, de repente, desaparezca +debajo de su control, solo porque durmieron o hicieron otra cosa por un +tiempo. + +Tenga en cuenta que el bloqueo **no** reemplaza el recuento de referencia. +El bloqueo se utiliza para mantener la coherencia de las estructuras de +datos, mientras que la referencia y contar es una técnica de gestión de +memoria. Por lo general, ambos son necesarios, y no deben confundirse entre +sí. + +De hecho, muchas estructuras de datos pueden tener dos niveles de conteo de +referencias, cuando hay usuarios de diferentes ``clases``. El conteo de +subclases cuenta el número de usuarios de la subclase y disminuye el conteo +global solo una vez, cuando el recuento de subclases llega a cero. + +Se pueden encontrar ejemplos de este tipo de ``recuento de referencias de +niveles múltiples`` en la gestión de memoria (``struct mm_struct``: +mm_users y mm_count), y en código del sistema de archivos +(``struct super_block``: s_count y s_active). + +Recuerde: si otro hilo puede encontrar su estructura de datos y usted no +tiene un recuento de referencias, es casi seguro que tiene un error. + +12) Macros, Enums y RTL +------------------------ + +Los nombres de macros que definen constantes y etiquetas en enumeraciones +(enums) están en mayúsculas. + +.. code-block:: c + + #define CONSTANTE 0x12345 + +Se prefieren los enums cuando se definen varias constantes relacionadas. + +Se aprecian los nombres de macro en MAYÚSCULAS, pero las macros que se +asemejan a funciones puede ser nombradas en minúscula. + +Generalmente, las funciones en línea son preferibles a las macros que se +asemejan a funciones. + +Las macros con varias instrucciones deben contenerse en un bloque do-while: + +.. code-block:: c + + #define macrofun(a, b, c) \ + do { \ + if (a == 5) \ + haz_esto(b, c); \ + } while (0) + +Cosas a evitar al usar macros: + +1) macros que afectan el flujo de control: + +.. code-block:: c + + #define FOO(x) \ + do { \ + if (blah(x) < 0) \ + return -EBUGGERED; \ + } while (0) + +es una **muy** mala idea. Parece una llamada de función pero sale de la +función de ``llamada``; no rompa los analizadores internos de aquellos que +leerán el código. + +2) macros que dependen de tener una variable local con un nombre mágico: + +.. code-block:: c + + #define FOO(val) bar(index, val) + +puede parecer algo bueno, pero es confuso como el infierno cuando uno lee +el código, y es propenso a romperse por cambios aparentemente inocentes. + +3) macros con argumentos que se usan como valores l: FOO(x) = y; le van +a morder si alguien, por ejemplo, convierte FOO en una función en línea. + +4) olvidarse de la precedencia: las macros que definen constantes usando +expresiones deben encerrar la expresión entre paréntesis. Tenga cuidado con +problemas similares con macros usando parámetros. + +.. code-block:: c + + #define CONSTANTE 0x4000 + #define CONSTEXP (CONSTANTE | 3) + +5) colisiones de espacio de nombres ("namespace") al definir variables +locales en macros que se asemejan a funciones: + +.. code-block:: c + + #define FOO(x) \ + ({ \ + typeof(x) ret; \ + ret = calc_ret(x); \ + (ret); \ + }) + +ret es un nombre común para una variable local -es menos probable que +__foo_ret colisione (coincida) con una variable existente. + +El manual de cpp trata las macros de forma exhaustiva. El manual interno de +gcc también cubre RTL, que se usa frecuentemente con lenguaje ensamblador +en el kernel. + +13) Imprimir mensajes del kernel +-------------------------------- + +A los desarrolladores del kernel les gusta ser vistos como alfabetizados. +Cuide la ortografía de los mensajes del kernel para causar una buena +impresión. No utilice contracciones incorrectas como ``dont``; use +``do not`` o ``don't`` en su lugar. Haga sus mensajes concisos, claros e +inequívocos. + +Los mensajes del kernel no tienen que terminar con un punto. + +Imprimir números entre paréntesis (%d) no agrega valor y debe evitarse. + +Hay varias modelos de macros de diagnóstico de driver en <linux/dev_printk.h> +que debe usar para asegurarse de que los mensajes coincidan con el +dispositivo correcto y driver, y están etiquetados con el nivel correcto: +dev_err(), dev_warn(), dev_info(), y así sucesivamente. Para mensajes que +no están asociados con un dispositivo particular, <linux/printk.h> define +pr_notice(), pr_info(), pr_warn(), pr_err(), etc. + +Crear buenos mensajes de depuración puede ser todo un desafío; y una vez +los tiene, pueden ser de gran ayuda para la resolución remota de problemas. +Sin embargo, la impresión de mensajes de depuración se maneja de manera +diferente a la impresión de otros mensajes que no son de depuración. +Mientras que las otras funciones pr_XXX() se imprimen incondicionalmente, +pr_debug() no lo hace; se compila fuera por defecto, a menos que DEBUG sea +definido o se establezca CONFIG_DYNAMIC_DEBUG. Eso es cierto para dev_dbg() +también, y una convención relacionada usa VERBOSE_DEBUG para agregar +mensajes dev_vdbg() a los ya habilitados por DEBUG. + +Muchos subsistemas tienen opciones de depuración de Kconfig para activar +-DDEBUG en el Makefile correspondiente; en otros casos, los archivos +usan #define DEBUG. Y cuando un mensaje de depuración debe imprimirse +incondicionalmente, por ejemplo si es ya dentro de una sección #ifdef +relacionada con la depuración, printk(KERN_DEBUG ...) puede ser usado. + +14) Reservando memoria +---------------------- + +El kernel proporciona los siguientes asignadores de memoria de propósito +general: kmalloc(), kzalloc(), kmalloc_array(), kcalloc(), vmalloc() y +vzalloc(). Consulte la documentación de la API para obtener más información. +a cerca de ellos. :ref:`Documentation/core-api/memory-allocation.rst +<memory_allocation>` + +La forma preferida para pasar el tamaño de una estructura es la siguiente: + +.. code-block:: c + + p = kmalloc(sizeof(*p), ...); + +La forma alternativa donde se deletrea el nombre de la estructura perjudica +la legibilidad, y presenta una oportunidad para un error cuando se cambia +el tipo de variable de puntero, pero el tamaño correspondiente de eso que +se pasa a un asignador de memoria no. + +Convertir el valor devuelto, que es un puntero vacío, es redundante. La +conversión desde el puntero vacío a cualquier otro tipo de puntero está +garantizado por la programación en idioma C. + +La forma preferida para asignar una matriz es la siguiente: + +.. code-block:: c + + p = kmalloc_array(n, sizeof(...), ...); + +La forma preferida para asignar una matriz a cero es la siguiente: + +.. code-block:: c + + p = kcalloc(n, sizeof(...), ...); + +Ambos casos verifican el desbordamiento en el tamaño de asignación n * +sizeof (...), y devuelven NULL si esto ocurrió. + +Todas estas funciones de asignación genéricas emiten un volcado de pila +(" stack dump") en caso de fallo cuando se usan sin __GFP_NOWARN, por lo +que no sirve de nada emitir un mensaje de fallo adicional cuando se +devuelva NULL. + +15) La enfermedad de inline +---------------------------- + +Parece haber una común percepción errónea de que gcc tiene una magica +opción "hazme más rápido" de aceleración, llamada ``inline`` (en línea). +Mientras que el uso de inlines puede ser apropiado (por ejemplo, como un +medio para reemplazar macros, consulte el Capítulo 12), muy a menudo no lo +es. El uso abundante de la palabra clave inline conduce a una mayor kernel, +que a su vez ralentiza el sistema en su conjunto, debido a una mayor huella +de icache para la CPU, y sencillamente porque hay menos memoria disponible +para el pagecache. Solo piense en esto; un fallo en la memoria caché de la +página provoca una búsqueda de disco, que tarda fácilmente 5 milisegundos. +Hay MUCHOS ciclos de CPU que puede entrar en estos 5 milisegundos. + +Una razonable regla general es no poner funciones inline que tengan más de +3 líneas de código en ellas. Una excepción a esta regla son los casos en +que se sabe que un parámetro es una constante en tiempo de compilación, y +como resultado de esto, usted *sabe*, el compilador podrá optimizar la +mayor parte de su función en tiempo de compilación. Para un buen ejemplo de +este último caso, véase la función en línea kmalloc(). + +A menudo, la gente argumenta que agregar funciones en línea que son +estáticas y se usan solo una vez, es siempre una victoria ya que no hay +perdida de espacio. Mientras esto es técnicamente correcto, gcc es capaz de +incorporarlos automáticamente sin ayuda, y esta el problema de +mantenimiento de eliminar el inline, cuando un segundo usuario supera el +valor potencial de la pista que le dice a gcc que haga algo que habría +hecho de todos modos. + +16) Valores devueltos por función y sus nombres +----------------------------------------------- + +Las funciones pueden devolver valores de muchos tipos diferentes, y uno de +lo más común es un valor que indica si la función tuvo éxito o ha fallado. +Dicho valor se puede representar como un número entero de código de error +(-Exxx = falla, 0 = éxito) o un booleano ``con éxito`` (0 = falla, distinto +de cero = éxito). + +La mezcla de estos dos tipos de representaciones es una fuente fértil de +errores difíciles de encontrar. Si el lenguaje C incluyera una fuerte +distinción entre enteros y booleanos, el compilador encontraría estos +errores por nosotros... pero no lo hace. Para ayudar a prevenir tales +errores, siga siempre esta convención:: + + Si el nombre de una función es una acción o un comando imperativo, + la función debe devolver un número entero de código de error. si el nombre + es un predicado, la función debe devolver un valor booleano "exitoso". + +Por ejemplo, ``agregar trabajo`` es un comando, y la función +agregar_trabajo() devuelve 0 en caso de éxito o -EBUSY en caso de fracaso. +De la misma manera, ``dispositivo PCI presente`` es un predicado, y la +función pci_dev_present() devuelve 1 si tiene éxito en encontrar un +dispositivo coincidente o 0 si no es así. + +Todas las funciones EXPORTed (exportadas) deben respetar esta convención, +al igual que todas las funciones publicas. Las funciones privadas +(estáticas) no lo necesitan, pero es recomendado que lo hagan. + +Las funciones cuyo valor devuelto es el resultado real de un cálculo, en +lugar de una indicación de si el cómputo tuvo éxito, no están sujetas a +esta regla. Generalmente indican fallo al devolver valores fuera del rango +de resultados. Los ejemplos típicos serían funciones que devuelven +punteros; estos usan NULL o el mecanismo ERR_PTR para informar de fallos. + +17) Usando bool +---------------- + +El tipo bool del kernel Linux es un alias para el tipo C99 _Bool. Los +valores booleanos pueden solo evaluar a 0 o 1, y la conversión implícita o +explícita a bool convierte automáticamente el valor en verdadero o falso. +Cuando se utilizan tipos booleanos, +!! no se necesita construcción, lo que elimina una clase de errores. + +Cuando se trabaja con valores booleanos, se deben usar las definiciones +verdadera y falsa, en lugar de 1 y 0. + +Los tipos de devolución de función bool y las variables de pila siempre +se pueden usar cuando esto sea adecuado. Se recomienda el uso de bool para +mejorar la legibilidad y, a menudo, es una mejor opción que 'int' para +almacenar valores booleanos. + +No use bool si el diseño de la línea de caché o el tamaño del valor son +importantes, ya que su tamaño y la alineación varía según la arquitectura +compilada. Las estructuras que son optimizadas para la alineación y el +tamaño no debe usar bool. + +Si una estructura tiene muchos valores verdadero/falso, considere +consolidarlos en un bitfield con miembros de 1 bit, o usando un tipo de +ancho fijo apropiado, como u8. + +De manera similar, para los argumentos de función, se pueden consolidar +muchos valores verdaderos/falsos en un solo argumento bit a bit 'flags' y +'flags' a menudo, puede ser una alternativa de argumento más legible si los +sitios de llamada tienen constantes desnudas de tipo verdaderas/falsas. + +De lo contrario, el uso limitado de bool en estructuras y argumentos puede +mejorar la legibilidad. + +18) No reinvente las macros del kernel +--------------------------------------- + +El archivo de cabecera include/linux/kernel.h contiene una serie de macros +que debe usar, en lugar de programar explícitamente alguna variante de +estos por usted mismo. Por ejemplo, si necesita calcular la longitud de una +matriz, aproveche la macro + +.. code-block:: c + + #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) + +De manera similar, si necesita calcular el tamaño de algún miembro de la +estructura, use + +.. code-block:: c + + #define sizeof_field(t, f) (sizeof(((t*)0)->f)) + +También hay macros min() y max() que realizan una verificación estricta de +tipos si lo necesita. Siéntase libre de leer detenidamente ese archivo de +encabezado para ver qué más ya está definido y que no debe reproducir en su +código. + +19) Editores modeline y otros desastres +--------------------------------------- + +Algunos editores pueden interpretar la información de configuración +incrustada en los archivos fuente, indicado con marcadores especiales. Por +ejemplo, emacs interpreta las líneas marcadas como esto: + +.. code-block:: c + + -*- mode: c -*- + +O así: + +.. code-block:: c + + /* + Local Variables: + compile-command: "gcc -DMAGIC_DEBUG_FLAG foo.c" + End: + */ + +Vim interpreta los marcadores que se ven así: + +.. code-block:: c + + /* vim:set sw=8 noet */ + +No incluya ninguno de estos en los archivos fuente. La gente tiene sus +propias configuraciones del editor, y sus archivos de origen no deben +anularlos. Esto incluye marcadores para sangría y configuración de modo. +La gente puede usar su propio modo personalizado, o puede tener algún otro +método mágico para que la sangría funcione correctamente. + + +20) Ensamblador inline +----------------------- + +En el código específico de arquitectura, es posible que deba usar +ensamblador en línea para interactuar con funcionalidades de CPU o +plataforma. No dude en hacerlo cuando sea necesario. Sin embargo, no use +ensamblador en línea de forma gratuita cuando C puede hacer el trabajo. +Puede y debe empujar el hardware desde C cuando sea posible. + +Considere escribir funciones auxiliares simples que envuelvan bits comunes +de ensamblador, en lugar de escribirlos repetidamente con ligeras +variaciones. Recuerde que el ensamblador en línea puede usar parámetros C. + +Las funciones de ensamblador grandes y no triviales deben ir en archivos .S, +con su correspondientes prototipos de C definidos en archivos de encabezado +en C. Los prototipos de C para el ensamblador deben usar ``asmlinkage``. + +Es posible que deba marcar su declaración asm como volátil, para evitar que +GCC la elimine si GCC no nota ningún efecto secundario. No siempre es +necesario hacerlo, sin embargo, y hacerlo innecesariamente puede limitar la +optimización. + +Al escribir una sola declaración de ensamblador en línea que contiene +múltiples instrucciones, ponga cada instrucción en una línea separada en +una string separada, y termine cada string excepto la última con ``\n\t`` +para indentar correctamente la siguiente instrucción en la salida en +ensamblador: + +.. code-block:: c + + asm ("magic %reg1, #42\n\t" + "more_magic %reg2, %reg3" + : /* outputs */ : /* inputs */ : /* clobbers */); + +21) Compilación condicional +--------------------------- + +Siempre que sea posible, no use condicionales de preprocesador (#if, +#ifdef) en archivos .c; de lo contrario, el código es más difícil de leer y +la lógica más difícil de seguir. En cambio, use dichos condicionales en un +archivo de encabezado que defina funciones para usar en esos archivos .c, +proporcionando versiones de código auxiliar sin operación en el caso #else, +y luego llame a estas funciones incondicionalmente desde archivos .c. El +compilador evitará generar cualquier código para las llamadas restantes, +produciendo resultados idénticos, pero la lógica es fácil de seguir. + +Prefiera compilar funciones completas, en lugar de porciones de funciones o +porciones de expresiones. En lugar de poner un ifdef en una expresión, +divida la totalidad de la expresión con una función de ayuda independiente +y aplique el condicional a esa función. + +Si tiene una función o variable que puede potencialmente quedar sin usar en +una configuración en particular, y el compilador advertiría sobre su +definición sin usar, marque la definición como __maybe_unused en lugar de +envolverla en un preprocesador condicional. (Sin embargo, si una función o +variable *siempre* acaba sin ser usada, bórrela.) + +Dentro del código, cuando sea posible, use la macro IS_ENABLED para +convertir un símbolo Kconfig en una expresión booleana de C, y utilícelo en +un condicional de C normal: + +.. code-block:: c + + if (IS_ENABLED(CONFIG_SOMETHING)) { + ... + } + +El compilador "doblará"" constantemente el condicional e incluirá o +excluirá el bloque de código al igual que con un #ifdef, por lo que esto no +agregará ningún tiempo de gastos generales en ejecución. Sin embargo, este +enfoque todavía permite que el compilador de C vea el código dentro del +bloque, y verifique que sea correcto (sintaxis, tipos, símbolo, referencias, +etc.). Por lo tanto, aún debe usar un #ifdef si el código dentro del bloque +hace referencia a símbolos que no existirán si no se cumple la condición. + +Al final de cualquier bloque #if o #ifdef no trivial (más de unas pocas +líneas), incluya un comentario después de #endif en la misma línea, +anotando la expresión condicional utilizada. Por ejemplo: + +.. code-block:: c + + #ifdef CONFIG_SOMETHING + ... + #endif /* CONFIG_SOMETHING */ + +22) No rompa el kernel +----------------------- + +En general, la decisión de romper el kernel pertenece al usuario, más que +al desarrollador del kernel. + +Evite el panic() +**************** + +panic() debe usarse con cuidado y principalmente solo durante el arranque +del sistema. panic() es, por ejemplo, aceptable cuando se queda sin memoria +durante el arranque y no puede continuar. + +Use WARN() en lugar de BUG() +**************************** + +No agregue código nuevo que use cualquiera de las variantes BUG(), como +BUG(), BUG_ON() o VM_BUG_ON(). En su lugar, use una variante WARN*(), +preferiblemente WARN_ON_ONCE(), y posiblemente con código de recuperación. +El código de recuperación no es requerido si no hay una forma razonable de +recuperar, al menos parcialmente. + +"Soy demasiado perezoso para tener en cuenta los errores" no es una excusa +para usar BUG(). Importantes corrupciones internas sin forma de continuar +aún pueden usar BUG(), pero necesitan una buena justificación. + +Use WARN_ON_ONCE() en lugar de WARN() o WARN_ON() +************************************************* + +Generalmente, se prefiere WARN_ON_ONCE() a WARN() o WARN_ON(), porque es +común que una condición de advertencia dada, si ocurre, ocurra varias +veces. Esto puede llenar el registro del kernel, e incluso puede ralentizar +el sistema lo suficiente como para que el registro excesivo se convierta en +su propio, adicional problema. + +No haga WARN a la ligera +************************ + +WARN*() está diseñado para situaciones inesperadas que nunca deberían +suceder. Las macros WARN*() no deben usarse para nada que se espera que +suceda durante un funcionamiento normal. No hay "checkeos" previos o +posteriores a la condición, por ejemplo. De nuevo: WARN*() no debe usarse +para una condición esperada que vaya a activarse fácilmente, por ejemplo, +mediante acciones en el espacio del usuario. pr_warn_once() es una +alternativa posible, si necesita notificar al usuario de un problema. + +No se preocupe sobre panic_on_warn de usuarios +********************************************** + +Algunas palabras más sobre panic_on_warn: Recuerde que ``panic_on_warn`` es +una opción disponible del kernel, y que muchos usuarios configuran esta +opción. Esta es la razón por la que hay un artículo de "No haga WARN a la +ligera", arriba. Sin embargo, la existencia de panic_on_warn de usuarios no +es una razón válida para evitar el uso juicioso de WARN*(). Esto se debe a +que quien habilita panic_on_warn, explícitamente pidió al kernel que +fallara si se dispara un WARN*(), y tales usuarios deben estar preparados +para afrontar las consecuencias de un sistema que es algo más probable que +se rompa. + +Use BUILD_BUG_ON() para aserciones en tiempo de compilación +*********************************************************** + +El uso de BUILD_BUG_ON() es aceptable y recomendado, porque es una aserción +en tiempo de compilación, que no tiene efecto en tiempo de ejecución. + +Apéndice I) Referencias +----------------------- + +The C Programming Language, Segunda edicion +por Brian W. Kernighan and Dennis M. Ritchie. +Prentice Hall, Inc., 1988. +ISBN 0-13-110362-8 (paperback), 0-13-110370-9 (hardback). + +The Practice of Programming +por Brian W. Kernighan and Rob Pike. +Addison-Wesley, Inc., 1999. +ISBN 0-201-61586-X. + +manuales GCC - en cumplimiento con K&R y este texto - para cpp, gcc, +detalles de gcc y sangría, todo disponible en https://www.gnu.org/manual/ + +WG14 es el grupo de trabajo de estandarización internacional de la +programación en lenguaje C, URL: http://www.open-std.org/JTC1/SC22/WG14/ + +:ref:`process/coding-style.rst <codingstyle>` del kernel, por greg@kroah.com at OLS 2002: +http://www.kroah.com/linux/talks/ols_2002_kernel_codingstyle_talk/html/ diff --git a/Documentation/translations/sp_SP/process/index.rst b/Documentation/translations/sp_SP/process/index.rst new file mode 100644 index 000000000000..49a05f6a5544 --- /dev/null +++ b/Documentation/translations/sp_SP/process/index.rst @@ -0,0 +1,15 @@ +.. raw:: latex + + \renewcommand\thesection* + \renewcommand\thesubsection* + +.. include:: ../disclaimer-sp.rst + +.. _sp_process_index: + +.. toctree:: + :maxdepth: 1 + + submitting-patches + kernel-docs + coding-style diff --git a/Documentation/translations/sp_SP/process/kernel-docs.rst b/Documentation/translations/sp_SP/process/kernel-docs.rst new file mode 100644 index 000000000000..2f9b3df8f8fa --- /dev/null +++ b/Documentation/translations/sp_SP/process/kernel-docs.rst @@ -0,0 +1,187 @@ +.. include:: ../disclaimer-sp.rst + +:Original: :ref:`Documentation/process/kernel-docs.rst <kernel_docs>` +:Translator: Carlos Bilbao <carlos.bilbao@amd.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: http://vger.kernel.org/vger-lists.html + :URL: http://www.uwsg.indiana.edu/hypermail/linux/kernel/index.html + :URL: http://groups.google.com/group/mlist.linux.kernel + :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 diff --git a/Documentation/translations/sp_SP/process/submitting-patches.rst b/Documentation/translations/sp_SP/process/submitting-patches.rst new file mode 100644 index 000000000000..bf95ceb5e865 --- /dev/null +++ b/Documentation/translations/sp_SP/process/submitting-patches.rst @@ -0,0 +1,894 @@ +.. include:: ../disclaimer-sp.rst + +:Original: :ref:`Documentation/process/submitting-patches.rst <submittingpatches>` +:Translator: Carlos Bilbao <carlos.bilbao@amd.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 +:ref:`Documentation/process/maintainer-handbooks.rst <maintainer_handbooks_main>`. + +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/r/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 vger.kernel.org; +puedes encontrar un listado de estas en +http://vger.kernel.org/vger-lists.html. 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/admin-guide/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_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> + +NO!!!! Gente, no mas bombas enormes de parches a linux-kernel@vger.kernel.org! + <https://lore.kernel.org/r/20050711.125305.08322243.davem@davemloft.net> + +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 |