1.. include:: ../disclaimer-sp.rst 2 3:Original: :ref:`Documentation/process/adding-syscalls.rst <addsyscalls>` 4:Translator: Mauricio Fuentes <mauriciofb@gmail.com> 5 6.. _sp_addsyscalls: 7 8Agregando una Nueva Llamada del Sistema 9======================================= 10 11Este documento describe qué involucra agregar una nueva llamada del sistema 12al kernel Linux, más allá de la presentación y consejos normales en 13:ref:`Documentation/process/submitting-patches.rst <submittingpatches>` que 14también puede encontrar traducido a este idioma. 15 16Alternativas a Llamadas del Sistema 17----------------------------------- 18 19La primera cosa a considerar cuando se agrega una llamada al sistema es si 20alguna alternativa es adecuada en su lugar. Aunque las llamadas al sistema 21son los puntos de interacción entre el userspace y el kernel más obvios y 22tradicionales, existen otras posibilidades -- elija la que mejor se adecúe 23a su interfaz. 24 25 - Si se puede hacer que la operación se parezca a un objeto filesystem, 26 podría tener más sentido crear un nuevo sistema de ficheros o 27 dispositivo. Esto también hará más fácil encapsular la nueva 28 funcionalidad en un módulo del kernel en vez de requerir que sea 29 construido junto al kernel principal. 30 31 - Si la nueva funcionalidad involucra operaciones donde el kernel 32 notifica al userspace que algo ha pasado, entonces retornar un nuevo 33 descriptor de archivo para el objeto relevante permite al userspace 34 usar ``poll``/``select``/``epoll`` para recibir esta notificación. 35 36 - Sin embargo, operaciones que no mapean a operaciones similares a 37 :manpage:`read(2)`/:manpage:`write(2)` tienen que ser implementadas 38 como solicitudes :manpage:`ioctl(2)`, las cuales pueden llevar a un 39 API algo opaca. 40 41 - Si sólo está exponiendo información del runtime, un nuevo nodo en sysfs 42 (mire ``Documentation/filesystems/sysfs.rst``) o el filesystem ``/proc`` 43 podría ser más adecuado. Sin embargo, acceder a estos mecanismos 44 requiere que el filesystem relevante esté montado, lo que podría no ser 45 siempre el caso (e.g. en un ambiente namespaced/sandboxed/chrooted). 46 Evite agregar cualquier API a debugfs, ya que no se considera una 47 interfaz (interface) de 'producción' para el userspace. 48 49 - Si la operación es específica a un archivo o descriptor de archivo 50 específico, entonces la opción de comando adicional :manpage:`fcntl(2)` 51 podría ser más apropiada. Sin embargo, :manpage:`fcntl(2)` es una 52 llamada al sistema multiplexada que esconde mucha complejidad, así que 53 esta opción es mejor cuando la nueva funcion es analogamente cercana a 54 la funcionalidad existente :manpage:`fcntl(2)`, o la nueva funcionalidad 55 es muy simple (por ejemplo, definir/obtener un flag simple relacionado a 56 un descriptor de archivo). 57 58 - Si la operación es específica a un proceso o tarea particular, entonces 59 un comando adicional :manpage:`prctl(2)` podría ser más apropiado. Tal 60 como con :manpage:`fcntl(2)`, esta llamada al sistema es un multiplexor 61 complicado así que está reservado para comandos análogamente cercanos 62 del existente ``prctl()`` u obtener/definir un flag simple relacionado a 63 un proceso. 64 65Diseñando el API: Planeando para extensiones 66-------------------------------------------- 67 68Una nueva llamada del sistema forma parte del API del kernel, y tiene que 69ser soportada indefinidamente. Como tal, es una muy buena idea discutir 70explícitamente el interface en las listas de correo del kernel, y es 71importante planear para futuras extensiones del interface. 72 73(La tabla syscall está poblada con ejemplos históricos donde esto no se 74hizo, junto con los correspondientes seguimientos de los system calls -- 75``eventfd``/``eventfd2``, ``dup2``/``dup3``, ``inotify_init``/``inotify_init1``, 76``pipe``/``pipe2``, ``renameat``/``renameat2`` -- así que aprenda de la 77historia del kernel y planee extensiones desde el inicio.) 78 79Para llamadas al sistema más simples que sólo toman un par de argumentos, 80la forma preferida de permitir futuras extensiones es incluir un argumento 81flag a la llamada al sistema. Para asegurarse que el userspace pueda usar 82de forma segura estos flags entre versiones del kernel, revise si los flags 83contienen cualquier flag desconocido, y rechace la llamada al sistema (con 84``EINVAL``) si ocurre:: 85 86 if (flags & ~(THING_FLAG1 | THINGFLAG2 | THING_FLAG3)) 87 return -EINVAL; 88 89(Si no hay valores de flags usados aún, revise que los argumentos del flag 90sean cero.) 91 92Para llamadas al sistema más sofisticadas que involucran un gran número de 93argumentos, es preferible encapsular la mayoría de los argumentos en una 94estructura que sea pasada a través de un puntero. Tal estructura puede 95hacer frente a futuras extensiones mediante la inclusión de un argumento de 96tamaño en la estructura:: 97 98 struct xyzzy_params { 99 u32 size; /* userspace define p->size = sizeof(struct xyzzy_params) */ 100 u32 param_1; 101 u64 param_2; 102 u64 param_3; 103 }; 104 105Siempre que cualquier campo añadido subsecuente, digamos ``param_4``, sea 106diseñado de forma tal que un valor cero, devuelva el comportamiento previo, 107entonces permite versiones no coincidentes en ambos sentidos: 108 109 - Para hacer frente a programas del userspace más modernos, haciendo 110 llamadas a un kernel más antiguo, el código del kernel debe revisar que 111 cualquier memoria más allá del tamaño de la estructura sea cero (revisar 112 de manera efectiva que ``param_4 == 0``). 113 - Para hacer frente a programas antiguos del userspace haciendo llamadas a 114 un kernel más nuevo, el código del kernel puede extender con ceros, una 115 instancia más pequeña de la estructura (definiendo efectivamente 116 ``param_4 == 0``). 117 118Revise :manpage:`perf_event_open(2)` y la función ``perf_copy_attr()`` (en 119``kernel/events/code.c``) para un ejemplo de esta aproximación. 120 121 122Diseñando el API: Otras consideraciones 123--------------------------------------- 124 125Si su nueva llamada al sistema permite al userspace hacer referencia a un 126objeto del kernel, esta debería usar un descriptor de archivo como el 127manipulador de ese objeto -- no invente un nuevo tipo de objeto manipulador 128userspace cuando el kernel ya tiene mecanismos y semánticas bien definidas 129para usar los descriptores de archivos. 130 131Si su nueva llamada a sistema :manpage:`xyzzy(2)` retorna un nuevo 132descriptor de archivo, entonces el argumento flag debe incluir un valor que 133sea equivalente a definir ``O_CLOEXEC`` en el nuevo FD. Esto hace posible 134al userspace acortar la brecha de tiempo entre ``xyzzy()`` y la llamada a 135``fcntl(fd, F_SETFD, FD_CLOEXEC)``, donde un ``fork()`` inesperado y 136``execve()`` en otro hilo podrían filtrar un descriptor al programa 137ejecutado. (Sin embargo, resista la tentación de reusar el valor actual de 138la constante ``O_CLOEXEC``, ya que es específica de la arquitectura y es 139parte de un espacio numerado de flags ``O_*`` que está bastante lleno.) 140 141Si su llamada de sistema retorna un nuevo descriptor de archivo, debería 142considerar también que significa usar la familia de llamadas de sistema 143:manpage:`poll(2)` en ese descriptor de archivo. Hacer un descriptor de 144archivo listo para leer o escribir es la forma normal para que el kernel 145indique al espacio de usuario que un evento ha ocurrido en el 146correspondiente objeto del kernel. 147 148Si su nueva llamada de sistema :manpage:`xyzzy(2)` involucra algún nombre 149de archivo como argumento:: 150 151 int sys_xyzzy(const char __user *path, ..., unsigned int flags); 152 153debería considerar también si una versión :manpage:`xyzzyat(2)` es mas 154apropiada:: 155 156 int sys_xyzzyat(int dfd, const char __user *path, ..., unsigned int flags); 157 158Esto permite más flexibilidad en como el userspace especifica el archivo en 159cuestión; en particular esto permite al userspace pedir la funcionalidad a 160un descriptor de archivo ya abierto usando el flag ``AT_EMPTY_PATH``, 161efectivamente dando una operación :manpage:`fxyzzy(3)` gratis:: 162 163 - xyzzyat(AT_FDCWD, path, ..., 0) es equivalente a xyzzy(path, ...) 164 - xyzzyat(fd, "", ..., AT_EMPTY_PATH) es equivalente a fxyzzy(fd, ...) 165 166(Para más detalles sobre la explicación racional de las llamadas \*at(), 167revise el man page :manpage:`openat(2)`; para un ejemplo de AT_EMPTY_PATH, 168mire el man page :manpage:`fstatat(2)` manpage.) 169 170Si su nueva llamada de sistema :manpage:`xyzzy(2)` involucra un parámetro 171describiendo un describiendo un movimiento dentro de un archivo, ponga de 172tipo ``loff_t`` para que movimientos de 64-bit puedan ser soportados 173incluso en arquitecturas de 32-bit. 174 175Si su nueva llamada de sistema :manpage:`xyzzy` involucra una 176funcionalidad privilegiada, esta necesita ser gobernada por la capability 177bit linux apropiada (revisado con una llamada a ``capable()``), como se 178describe en el man page :manpage:`capabilities(7)`. Elija una parte de 179capability linux que govierne las funcionalidades relacionadas, pero trate 180de evitar combinar muchas funciones sólo relacionadas vagamente bajo la 181misma sección, ya que va en contra de los propósitos de las capabilities de 182dividir el poder del usuario root. En particular, evite agregar nuevos usos 183de la capacidad ya demasiado general de la capabilities ``CAP_SYS_ADMIN``. 184 185Si su nueva llamada de sistema :manpage:`xyzzy(2)` manipula un proceso que 186no es el proceso invocado, este debería ser restringido (usando una llamada 187a ``ptrace_may_access()``) de forma que el único proceso con los mismos 188permisos del proceso objetivo, o con las capacidades (capabilities) 189necesarias, pueda manipulador el proceso objetivo. 190 191Finalmente, debe ser conciente de que algunas arquitecturas no-x86 tienen 192un manejo más sencillo si los parámetros que son explícitamente 64-bit 193caigan en argumentos enumerados impares (i.e. parámetros 1,3,5), para 194permitir el uso de pares contiguos de registros 32-bits. (Este cuidado no 195aplica si el argumento es parte de una estructura que se pasa a través de 196un puntero.) 197 198Proponiendo el API 199------------------ 200 201Para hacer una nueva llamada al sistema fácil de revisar, es mejor dividir 202el patchset (conjunto de parches) en trozos separados. Estos deberían 203incluir al menos los siguientes items como commits distintos (cada uno de 204los cuales se describirá más abajo): 205 206 - La implementación central de la llamada al sistema, junto con 207 prototipos, numeración genérica, cambios Kconfig e implementaciones de 208 rutinas de respaldo (fallback stub) 209 - Conectar la nueva llamada a sistema a una arquitectura particular, 210 usualmente x86 (incluyendo todas las x86_64, x86_32 y x32). 211 - Una demostración del use de la nueva llamada a sistema en el userspace 212 vía un selftest en ``tools/testing/selftest/``. 213 - Un borrador de man-page para la nueva llamada a sistema, ya sea como 214 texto plano en la carta de presentación, o como un parche (separado) 215 para el repositorio man-pages. 216 217Nuevas propuestas de llamadas de sistema, como cualquier cambio al API del 218kernel, debería siempre ser copiado a linux-api@vger.kernel.org. 219 220 221Implementation de Llamada de Sistema Generica 222--------------------------------------------- 223 224La entrada principal a su nueva llamada de sistema :manpage:`xyzzy(2)` será 225llamada ``sys_xyzzy()``, pero incluya este punto de entrada con la macro 226``SYSCALL_DEFINEn()`` apropiada en vez de explicitamente. El 'n' indica el 227numero de argumentos de la llamada de sistema, y la macro toma el nombre de 228la llamada de sistema seguida por el par (tipo, nombre) para los parámetros 229como argumentos. Usar esta macro permite a la metadata de la nueva llamada 230de sistema estar disponible para otras herramientas. 231 232El nuevo punto de entrada también necesita un prototipo de función 233correspondiente en ``include/linux/syscalls.h``, marcado como asmlinkage 234para calzar en la manera en que las llamadas de sistema son invocadas:: 235 236 asmlinkage long sys_xyzzy(...); 237 238Algunas arquitecturas (e.g. x86) tienen sus propias tablas de syscall 239específicas para la arquitectura, pero muchas otras arquitecturas comparten 240una tabla de syscall genéricas. Agrega su nueva llamada de sistema a la 241lista genérica agregando una entrada a la lista en 242``include/uapi/asm-generic/unistd.h``:: 243 244 #define __NR_xyzzy 292 245 __SYSCALL(__NR_xyzzy, sys_xyzzy ) 246 247También actualice el conteo de __NR_syscalls para reflejar la llamada de 248sistema adicional, y note que si multiples llamadas de sistema nuevas son 249añadidas en la misma ventana unida, su nueva llamada de sistema podría 250tener que ser ajustada para resolver conflictos. 251 252El archivo ``kernel/sys_ni.c`` provee una implementación fallback stub 253(rutina de respaldo) para cada llamada de sistema, retornando ``-ENOSYS``. 254Incluya su nueva llamada a sistema aquí también:: 255 256 COND_SYSCALL(xyzzy); 257 258Su nueva funcionalidad del kernel, y la llamada de sistema que la controla, 259debería normalmente ser opcional, así que incluya una opción ``CONFIG`` 260(tipicamente en ``init/Kconfig``) para ella. Como es usual para opciones 261``CONFIG`` nuevas: 262 263 - Incluya una descripción para la nueva funcionalidad y llamada al sistema 264 controlada por la opción. 265 - Haga la opción dependiendo de EXPERT si esta debe estar escondida de los 266 usuarios normales. 267 - Haga que cualquier nuevo archivo fuente que implemente la función 268 dependa de la opción CONFIG en el Makefile (e.g. 269 ``obj-$(CONFIG_XYZZY_SYSCALL) += xyzzy.o``). 270 - Revise dos veces que el kernel se siga compilando con la nueva opción 271 CONFIG apagada. 272 273Para resumir, necesita un commit que incluya: 274 275 - una opción ``CONFIG`` para la nueva función, normalmente en ``init/Kconfig`` 276 - ``SYSCALL_DEFINEn(xyzzy, ...)`` para el punto de entrada 277 - El correspondiente prototipo en ``include/linux/syscalls.h`` 278 - Una entrada genérica en ``include/uapi/asm-generic/unistd.h`` 279 - fallback stub en ``kernel/sys_ni.c`` 280 281 282Implementación de Llamada de Sistema x86 283---------------------------------------- 284 285Para conectar su nueva llamada de sistema a plataformas x86, necesita 286actualizar las tablas maestras syscall. Asumiendo que su nueva llamada de 287sistema ni es especial de alguna manera (revise abajo), esto involucra una 288entrada "común" (para x86_64 y x86_32) en 289arch/x86/entry/syscalls/syscall_64.tbl:: 290 291 333 common xyzz sys_xyzzy 292 293y una entrada "i386" en ``arch/x86/entry/syscalls/syscall_32.tbl``:: 294 295 380 i386 xyzz sys_xyzzy 296 297De nuevo, estos número son propensos de ser cambiados si hay conflictos en 298la ventana de integración relevante. 299 300 301Compatibilidad de Llamadas de Sistema (Genérica) 302------------------------------------------------ 303 304Para la mayoría de llamadas al sistema la misma implementación 64-bit puede 305ser invocada incluso cuando el programa de userspace es en si mismo 32-bit; 306incluso si los parámetros de la llamada de sistema incluyen un puntero 307explícito, esto es manipulado de forma transparente. 308 309Sin embargo, existe un par de situaciones donde se necesita una capa de 310compatibilidad para lidiar con las diferencias de tamaño entre 32-bit y 31164-bit. 312 313La primera es si el kernel 64-bit también soporta programas del userspace 31432-bit, y por lo tanto necesita analizar areas de memoria del (``__user``) 315que podrían tener valores tanto 32-bit como 64-bit. En particular esto se 316necesita siempre que un argumento de la llamada a sistema es: 317 318 - un puntero a un puntero 319 - un puntero a un struc conteniendo un puntero (por ejemplo 320 ``struct iovec __user *``) 321 - un puntero a un type entero de tamaño entero variable (``time_t``, 322 ``off_t``, ``long``, ...) 323 - un puntero a un struct conteniendo un type entero de tamaño variable. 324 325La segunda situación que requiere una capa de compatibilidad es cuando uno 326de los argumentos de la llamada a sistema tiene un argumento que es 327explícitamente 64-bit incluso sobre arquitectura 32-bit, por ejemplo 328``loff_t`` o ``__u64``. En este caso, el valor que llega a un kernel 64-bit 329desde una aplicación de 32-bit se separará en dos valores de 32-bit, los 330que luego necesitan ser reensamblados en la capa de compatibilidad. 331 332(Note que un argumento de una llamada a sistema que sea un puntero a un 333type explicitamente de 64-bit **no** necesita una capa de compatibilidad; 334por ejemplo, los argumentos de :manpage:`splice(2)`) del tipo 335``loff_t __user *`` no significan la necesidad de una llamada a sistema 336``compat_``.) 337 338La versión compatible de la llamada de sistema se llama 339``compat_sys_xyzzy()``, y se agrega con la macro 340``COMPAT_SYSCALL_DEFINEn``, de manera análoga a SYSCALL_DEFINEn. Esta 341versión de la implementación se ejecuta como parte de un kernel de 64-bit, 342pero espera recibir parametros con valores 32-bit y hace lo que tenga que 343hacer para tratar con ellos. (Típicamente, la versión ``compat_sys_`` 344convierte los valores a versiones de 64 bits y llama a la versión ``sys_`` 345o ambas llaman a una función de implementación interna común.) 346 347El punto de entrada compat también necesita un prototipo de función 348correspondiente, en ``include/linux/compat.h``, marcado como asmlinkage 349para igualar la forma en que las llamadas al sistema son invocadas:: 350 351 asmlinkage long compat_sys_xyzzy(...); 352 353Si la nueva llamada al sistema involucra una estructura que que se dispone 354de forma distinta en sistema de 32-bit y 64-bit, digamos 355``struct xyzzy_args``, entonces el archivo de cabecera 356include/linux/compat.h también debería incluir una versión compatible de la 357estructura (``struct compat_xyzzy_args``) donde cada campo de tamaño 358variable tiene el tipo ``compat_`` apropiado que corresponde al tipo en 359``struct xyzzy_args``. La rutina ``compat_sys_xyzzy()`` puede entonces usar 360esta estructura ``compat_`` para analizar los argumentos de una invocación 361de 32-bit. 362 363Por ejemplo, si hay campos:: 364 365 struct xyzzy_args { 366 const char __user *ptr; 367 __kernel_long_t varying_val; 368 u64 fixed_val; 369 /* ... */ 370 }; 371 372en struct xyzzy_args, entonces struct compat_xyzzy_args debe tener:: 373 374 struct compat_xyzzy_args { 375 compat_uptr_t ptr; 376 compat_long_t varying_val; 377 u64 fixed_val; 378 /* ... */ 379 }; 380 381la lista genérica de llamadas al sistema también necesita ajustes para 382permitir la versión compat; la entrada en 383``include/uapi/asm-generic/unistd.h`` debería usar ``__SC_COMP`` en vez de 384``__SYSCALL``:: 385 386 #define __NR_xyzzy 292 387 __SC_COMP(__NR_xyzzy, sys_xyzzy, compat_sys_xyzzy) 388 389Para resumir, necesita: 390 391 - una ``COMPAT_SYSCALL_DEFINEn(xyzzy, ...)`` para el punto de entrada de compat. 392 - el prototipo correspondiente en ``include/linux/compat.h`` 393 - (en caso de ser necesario) un struct de mapeo de 32-bit en ``include/linux/compat.h`` 394 - una instancia de ``__SC_COMP`` no ``__SYSCALL`` en ``include/uapi/asm-generic/unistd.h`` 395 396Compatibilidad de Llamadas de Sistema (x86) 397------------------------------------------- 398 399Para conectar la arquitectura x86 de una llamada al sistema con una versión 400de compatibilidad, las entradas en las tablas de syscall deben ser 401ajustadas. 402 403Primero, la entrada en ``arch/x86/entry/syscalls/syscall_32.tbl`` recibe 404una columna extra para indicar que un programa del userspace de 32-bit 405corriendo en un kernel de 64-bit debe llegar al punto de entrada compat:: 406 407 380 i386 xyzzy sys_xyzzy __ia32_compat_sys_xyzzy 408 409Segundo, tienes que averiguar qué debería pasar para la versión x32 ABI de 410la nueva llamada al sistema. Aquí hay una elección: el diseño de los 411argumentos debería coincidir con la versión de 64-bit o la versión de 41232-bit. 413 414Si hay involucrado un puntero-a-puntero, la decisión es fácil: x32 es 415ILP32, por lo que el diseño debe coincidir con la versión 32-bit, y la 416entrada en ``arch/x86/entry/syscalls/syscall_64.tbl`` se divide para que 417progamas 32-bit lleguen al envoltorio de compatibilidad:: 418 419 333 64 xyzzy sys_xyzzy 420 ... 421 555 x32 xyzzy __x32_compat_sys_xyzzy 422 423Si no hay punteros involucrados, entonces es preferible reutilizar el system 424call 64-bit para el x32 ABI (y consecuentemente la entrada en 425arch/x86/entry/syscalls/syscall_64.tbl no se cambia). 426 427En cualquier caso, debes revisar que lo tipos involucrados en su diseño de 428argumentos de hecho asigne exactamente de x32 (-mx32) a 32-bit(-m32) o 429equivalentes 64-bit (-m64). 430 431 432Llamadas de Sistema Retornando a Otros Lugares 433---------------------------------------------- 434 435Para la mayoría de las llamadas al sistema, una vez que se la llamada al 436sistema se ha completado el programa de usuario continúa exactamente donde 437quedó -- en la siguiente instrucción, con el stack igual y la mayoría de 438los registros igual que antes de la llamada al sistema, y con el mismo 439espacio en la memoria virtual. 440 441Sin embargo, unas pocas llamadas al sistema hacen las cosas diferente. 442Estas podrían retornar a una ubicación distinta (``rt_sigreturn``) o 443cambiar el espacio de memoria (``fork``/``vfork``/``clone``) o incluso de 444arquitectura (``execve``/``execveat``) del programa. 445 446Para permitir esto, la implementación del kernel de la llamada al sistema 447podría necesitar guardar y restaurar registros adicionales al stak del 448kernel, brindandole control completo de donde y cómo la ejecución continúa 449después de la llamada a sistema. 450 451Esto es arch-specific, pero típicamente involucra definir puntos de entrada 452assembly que guardan/restauran registros adicionales e invocan el punto de 453entrada real de la llamada a sistema. 454 455Para x86_64, esto es implementado como un punto de entrada ``stub_xyzzy`` 456en ``arch/x86/entry/entry_64.S``, y la entrada en la tabla syscall 457(``arch/x86/entry/syscalls/syscall_32.tbl``) es ajustada para calzar:: 458 459 333 common xyzzy stub_xyzzy 460 461El equivalente para programas 32-bit corriendo en un kernel 64-bit es 462normalmente llamado ``stub32_xyzzy`` e implementado en 463``arch/x86/entry/entry_64_compat.S``, con el correspondiente ajuste en la 464tabla syscall en ``arch/x86/syscalls/syscall_32.tbl``:: 465 466 380 i386 xyzzy sys_xyzzy stub32_xyzzy 467 468Si la llamada a sistema necesita una capa de compatibilidad (como en la 469sección anterior) entonces la versión ``stub32_`` necesita llamar a la 470versión ``compat_sys_`` de la llamada a sistema, en vez de la versión 471nativa de 64-bit. También, si la implementación de la versión x32 ABI no es 472comun con la versión x86_64, entonces su tabla syscall también necesitará 473invocar un stub que llame a la versión ``compat_sys_`` 474 475Para completar, también es agradable configurar un mapeo de modo que el 476user-mode linux todavía funcione -- su tabla syscall referenciará 477stub_xyzzy, pero el UML construido no incluye una implementación 478``arch/x86/entry/entry_64.S``. Arreglar esto es tan simple como agregar un 479#define a ``arch/x86/um/sys_call_table_64.c``:: 480 481 #define stub_xyzzy sys_xyzzy 482 483 484Otros detalles 485-------------- 486 487La mayoría del kernel trata las llamadas a sistema de manera genérica, pero 488está la excepción ocasional que pueda requerir actualización para su 489llamada a sistema particular. 490 491El subsistema de auditoría es un caso especial; este incluye funciones 492(arch-specific) que clasifican algunos tipos especiales de llamadas al 493sistema -- específicamente file open (``open``/``openat``), program 494execution (``execve`` /``execveat``) o operaciones multiplexores de socket 495(``socketcall``). Si su nueva llamada de sistema es análoga a alguna de 496estas, entonces el sistema auditor debe ser actualizado. 497 498Más generalmente, si existe una llamada al sistema que sea análoga a su 499nueva llamada al sistema, entonces vale la pena hacer un grep a todo el 500kernel de la llamada a sistema existente, para revisar que no exista otro 501caso especial. 502 503 504Testing 505------- 506 507Una nueva llamada al sistema debe obviamente ser probada; también es útil 508proveer a los revisores con una demostración de cómo los programas del 509userspace usarán la llamada al sistema. Una buena forma de combinar estos 510objetivos es incluir un simple programa self-test en un nuevo directorio 511bajo ``tools/testing/selftests/``. 512 513Para una nueva llamada al sistema, obviamente no habrá una función 514envoltorio libc por lo que el test necesitará ser invocado usando 515``syscall()``; también, si la llamada al sistema involucra una nueva 516estructura userspace-visible, el encabezado correspondiente necesitará ser 517instalado para compilar el test. 518 519Asegure que selftest corra satisfactoriamente en todas las arquitecturas 520soportadas. Por ejemplo, revise si funciona cuando es compilado como un 521x86_64 (-m64), x86_32 (-m32) y x32 (-mx32) programa ABI. 522 523Para pruebas más amplias y exhautivas de la nueva funcionalidad, también 524debería considerar agregar tests al Linus Test Project, o al proyecto 525xfstests para cambios filesystem-related 526 527 - https://linux-test-project.github.io/ 528 - git://git.kernel.org/pub/scm/fs/xfs/xfstests-dev.git 529 530 531Man Page 532-------- 533 534Todas las llamada al sistema nueva deben venir con un man page completo, 535idealmente usando groff markup, pero texto plano también funciona. Si se 536usa groff, es útil incluir una versión ASCII pre-renderizada del man-page 537en el cover del email para el patchset, para la conveniencia de los 538revisores. 539 540El man page debe ser cc'do a linux-man@vger.kernel.org 541Para más detalles, revise https://www.kernel.org/doc/man-pages/patches.html 542 543 544No invoque las llamadas de sistemas en el kernel 545------------------------------------------------ 546 547Las llamadas al sistema son, cómo se declaró más arriba, puntos de 548interacción entre el userspace y el kernel. Por lo tanto, las funciones de 549llamada al sistema como ``sys_xyzzy()`` o ``compat_sys_xyzzy()`` deberían 550ser llamadas sólo desde el userspace vía la tabla de syscall, pero no de 551otro lugar en el kernel. Si la funcionalidad syscall es útil para ser usada 552dentro del kernel, necesita ser compartida entre syscalls nuevas o 553antiguas, o necesita ser compartida entre una syscall y su variante de 554compatibilidad, esta debería ser implementada mediante una función "helper" 555(como ``ksys_xyzzy()``). Esta función del kernel puede ahora ser llamada 556dentro del syscall stub (``sys_xyzzy()``), la syscall stub de 557compatibilidad (``compat_sys_xyzzy()``), y/o otro código del kernel. 558 559Al menos en 64-bit x86, será un requerimiento duro desde la v4.17 en 560adelante no invocar funciones de llamada al sistema (system call) en el 561kernel. Este usa una convención de llamada diferente para llamadas al 562sistema donde ``struct pt_regs`` es decodificado on-the-fly en un 563envoltorio syscall que luego entrega el procesamiento al syscall real. Esto 564significa que sólo aquellos parámetros que son realmente necesarios para 565una syscall específica son pasados durante la entrada del syscall, en vez 566de llenar en seis registros de CPU con contenido random del userspace todo 567el tiempo (los cuales podrían causar serios problemas bajando la cadena de 568llamadas). 569 570Más aún, reglas sobre cómo se debería acceder a la data pueden diferir 571entre la data del kernel y la data de usuario. Esta es otra razón por la 572cual llamar a ``sys_xyzzy()`` es generalmente una mala idea. 573 574Excepciones a esta regla están permitidas solamente en overrides 575específicos de arquitectura, envoltorios de compatibilidad específicos de 576arquitectura, u otro código en arch/. 577 578 579Referencias y fuentes 580--------------------- 581 582 - Artículo LWN de Michael Kerrisk sobre el uso de argumentos flags en llamadas al 583 sistema: 584 https://lwn.net/Articles/585415/ 585 - Artículo LWN de Michael Kerrisk sobre cómo manejar flags desconocidos en una 586 llamada al sistema: https://lwn.net/Articles/588444/ 587 - Artículo LWN de Jake Edge describiendo restricciones en argumentos en 588 64-bit system call: https://lwn.net/Articles/311630/ 589 - Par de artículos LWN de David Drysdale que describen la ruta de implementación 590 de llamadas al sistema en detalle para v3.14: 591 592 - https://lwn.net/Articles/604287/ 593 - https://lwn.net/Articles/604515/ 594 595 - Requerimientos arquitectura-específicos para llamadas al sistema son discutidos en el 596 :manpage:`syscall(2)` man-page: 597 http://man7.org/linux/man-pages/man2/syscall.2.html#NOTES 598 - Recopilación de emails de Linus Torvalds discutiendo problemas con ``ioctl()``: 599 https://yarchive.net/comp/linux/ioctl.html 600 - "How to not invent kernel interfaces", Arnd Bergmann, 601 https://www.ukuug.org/events/linux2007/2007/papers/Bergmann.pdf 602 - Artículo LWN de Michael Kerrisk sobre evitar nuevos usos de CAP_SYS_ADMIN: 603 https://lwn.net/Articles/486306/ 604 - Recomendaciones de Andrew Morton que toda la información relacionada a una nueva 605 llamada al sistema debe venir en el mismo hilo de correos: 606 https://lore.kernel.org/r/20140724144747.3041b208832bbdf9fbce5d96@linux-foundation.org 607 - Recomendaciones de Michael Kerrisk que una nueva llamada al sistema debe venir 608 con un man-page: https://lore.kernel.org/r/CAKgNAkgMA39AfoSoA5Pe1r9N+ZzfYQNvNPvcRN7tOvRb8+v06Q@mail.gmail.com 609 - Sugerencias de Thomas Gleixner que conexiones x86 deben ir en commits 610 separados: https://lore.kernel.org/r/alpine.DEB.2.11.1411191249560.3909@nanos 611 - Sugerencias de Greg Kroah-Hartman que es bueno para las nueva llamadas al sistema 612 que vengan con man-page y selftest: https://lore.kernel.org/r/20140320025530.GA25469@kroah.com 613 - Discusión de Michael Kerrisk de nuevas system call vs. extensiones :manpage:`prctl(2)`: 614 https://lore.kernel.org/r/CAHO5Pa3F2MjfTtfNxa8LbnkeeU8=YJ+9tDqxZpw7Gz59E-4AUg@mail.gmail.com 615 - Sugerencias de Ingo Molnar que llamadas al sistema que involucran múltiples 616 argumentos deben encapsular estos argumentos en una estructura, la cual incluye 617 un campo de tamaño para futura extensibilidad: https://lore.kernel.org/r/20150730083831.GA22182@gmail.com 618 - Enumerando rarezas por la (re-)utilización de O_* numbering space flags: 619 620 - commit 75069f2b5bfb ("vfs: renumber FMODE_NONOTIFY and add to uniqueness 621 check") 622 - commit 12ed2e36c98a ("fanotify: FMODE_NONOTIFY and __O_SYNC in sparc 623 conflict") 624 - commit bb458c644a59 ("Safer ABI for O_TMPFILE") 625 626 - Discusión de Matthew Wilcox sobre las restricciones en argumentos 64-bit: 627 https://lore.kernel.org/r/20081212152929.GM26095@parisc-linux.org 628 - Recomendaciones de Greg Kroah-Hartman sobre flags desconocidos deben ser 629 vigilados: https://lore.kernel.org/r/20140717193330.GB4703@kroah.com 630 - Recomendaciones de Linus Torvalds que las llamadas al sistema x32 deben favorecer 631 compatibilidad con versiones 64-bit sobre versiones 32-bit: 632 https://lore.kernel.org/r/CA+55aFxfmwfB7jbbrXxa=K7VBYPfAvmu3XOkGrLbB1UFjX1+Ew@mail.gmail.com 633