diff --git a/documentation/content/es/articles/geom-class/_index.adoc b/documentation/content/es/articles/geom-class/_index.adoc new file mode 100644 index 0000000000..d98fda2da8 --- /dev/null +++ b/documentation/content/es/articles/geom-class/_index.adoc @@ -0,0 +1,362 @@ +--- +authors: + - + author: 'Ivan Voras' + email: ivoras@FreeBSD.org +description: 'Una guía sobre los detalles de GEOM y cómo escribir tu propia clase GEOM' +tags: ["GEOM", "kernel", "modules", "FreeBSD"] +title: 'Escribiendo una clase GEOM' +trademarks: ["freebsd", "intel", "general"] +--- + += Escribiendo una clase GEOM +:doctype: article +:toc: macro +:toclevels: 1 +:icons: font +:sectnums: +:sectnumlevels: 6 +:source-highlighter: rouge +:experimental: +:images-path: articles/geom-class/ + +ifdef::env-beastie[] +ifdef::backend-html5[] +include::shared/authors.adoc[] +include::shared/mirrors.adoc[] +include::shared/releases.adoc[] +include::shared/attributes/attributes-{{% lang %}}.adoc[] +include::shared/{{% lang %}}/teams.adoc[] +include::shared/{{% lang %}}/mailing-lists.adoc[] +include::shared/{{% lang %}}/urls.adoc[] +:imagesdir: ../../../images/{images-path} +endif::[] +ifdef::backend-pdf,backend-epub3[] +include::../../../../shared/asciidoctor.adoc[] +endif::[] +endif::[] + +ifndef::env-beastie[] +include::../../../../../shared/asciidoctor.adoc[] +endif::[] + +[.abstract-title] +Resumen + +Este texto documenta algunos puntos de partida en el desarrollo de clases GEOM y módulos del kernel en general. Se asume que el lector está familiarizado con la programación en C en modo usuario. + +''' + +toc::[] + +[[intro]] +== Introducción + +[[intro-docs]] +=== Documentación + +La documentación sobre la programación del kernel es escasa - es una de las pocas áreas donde casi no hay tutoriales amigables, y la frase, "¡usa el código fuente!", realmente es cierta. Sin embargo, hay algunos trozos (algunos de ellos muy desactualizados) flotando alrededor que deben estudiarse antes de comenzar a programar: + +* El extref:{developers-handbook}[FreeBSD Developer's Handbook] - parte del proyecto de documentación, no contiene nada específico a la programación del kernel sino más bien algo de información útil en general. +* El extref:{arch-handbook}[FreeBSD Architecture Handbook] - también parte del proyecto de documentación, contiene descripciones de varios servicios y procedimientos de bajo nivel. El capítulo más importante es el 13, extref:{arch-handbook}[Writing FreeBSD device drivers, driverbasics]. +* La sección Blueprints del sitio web http://www.freebsddiary.org[FreeBSD Diary] - contiene varios artículos interesantes sobre servicios del kernel. +* Las páginas del manual en la sección 9 — para documentación importante sobre las funciones del kernel. +* La página de manual man:geom[4] y http://phk.freebsd.dk/pubs/[PHK's GEOM slides] - para una introducción general al subsistema GEOM. +* Las páginas del manual man:g_bio[9], man:g_event[9], man:g_data[9], man:g_geom[9], man:g_provider[9], man:g_consumer[9], man:g_access[9] y otras enlazadas desde estas, para documentación sobre funcionalidades específicas. +* La página del manual man:style[9] - para documentación sobre las convenciones que debe seguir el estilo del código para todo aquel que se va a añadir al árbol de FreeBSD. + +[[prelim]] +== Preliminares + +La mejor forma de hacer desarrollo del kernel es tener (al menos) dos ordenadores separados. Uno de ellos debería de tener el entorno de desarrollo y el código fuente, y el otro sería usado para probar el código recién escrito, inicializando y montando su sistema de archivos a través de la red desde el primer ordenador. De esta forma, si el nuevo código contiene errores y bloquea el ordenador, esto no dañará el código fuente (ni ningún otro dato que este ejecutándose en "caliente"). El segundo sistema ni siquiera necesita un monitor adecuado. En su lugar, podría estar conectado con un cable serie o KVM al primer ordenador. + +Pero como no todo el mundo tiene dos o más ordenadores a mano, hay unas pocas cosas que se pueden hacer para preparar un entorno "en caliente" para desarrollar código del kernel. Esta configuración también se puede aplicar para desarrollar en una máquina virtual http://www.vmware.com/[VMWare] o http://www.qemu.org/[QEmu] (lo siguiente mejor después de tener una máquina como entorno dedicado). + +[[prelim-system]] +=== Modificar un sistema para el desarrollo + +Para cualquier programación del kernel, es obligatoria tener activada la opción `INVARIANTS`. Así que añade estas líneas a tu archivo de configuración del kernel: + +[.programlisting] +.... +options INVARIANT_SUPPORT +options INVARIANTS +.... + +Para tener un mayor nivel de depuración, también debes incluir el soporte de WITNESS, que te advertirá sobre errores relacionados con los bloqueos: + +[.programlisting] +.... +options WITNESS_SUPPORT +options WITNESS +.... + +Para depurar los volcados de memoria, se necesita un kernel con símbolos de depuración: + +[.programlisting] +.... + makeoptions DEBUG=-g +.... + +Con la forma habitual de instalar el kernel (`make installkernel`) no se instala el kernel de depuración de forma automática. Se llama [.filename]#kernel.debug# y se encuentra en [.filename]#/usr/obj/usr/src/sys/KERNELNAME/#. Por comodidad se debería copiar a [.filename]#/boot/kernel/#. + +Otra cosa útil es habilitar la depuración del kernel para que puedas examinar el kernel panic cuando suceda. Para esto, introduce las siguientes líneas en su archivo de configuración del kernel: + +[.programlisting] +.... +options KDB +options DDB +options KDB_TRACE +.... + +Para que esto funcione, es posible que necesites establecer un sysctl (si no está activado de forma predeterminada): + +[.programlisting] +.... + debug.debugger_on_panic=1 +.... + +Ocurrirán kernel panics, por lo que se debe tener cuidado con la cache del sistema de archivos. En particular, tener habilitadas las softupdates puede significar que la última versión del archivo podría perderse si se produce un kernel panic antes de que se haya hecho commit al almacenamiento. Deshabilitar las softupdates produce un gran impacto en el rendimiento, y no garantiza la consistencia de los datos. Para eso es necesario montar el sistema de archivos con la opción "sync". Como solución de compromiso, se pueden acortar los tiempos de espera de la cache de softupdates. Hay tres sysctls que son útiles para esto (lo mejor es establecerlas en [.filename]#/etc/sysctl.conf#): + +[.programlisting] +.... +kern.filedelay=5 +kern.dirdelay=4 +kern.metadelay=3 +.... + +Los números representan segundos. + +Para depurar los kernel panics, los volcados del kernel (core dumps) son necesarios. Dado que un kernel panic podría inutilizar los sistemas de archivos, este volcado de memoria se graba primero en una partición sin formato (raw). Por lo general, ésta es la partición swap. Esta partición debe ser al menos tan grande como la RAM física del ordenador. En el siguiente arranque, el volcado se copia en un archivo normal. Esto sucede después de que los sistemas de archivos se verifiquen y monten, y antes de habilitar la swap. Este proceso se controla con dos variables en [.filename]#/etc/rc.conf#: + +[.programlisting] +.... +dumpdev="/dev/ad0s4b" +dumpdir="/usr/core +.... + +La variable `dumpdev` especifica la partición swap y `dumpdir` le indica al sistema dónde copiar el dore dump al reiniciar. + +Escribir volcados del kernel es lento y lleva mucho tiempo, por lo que si tienes mucha memoria (>256M) y muchos kernel panics, puede ser frustrante sentarse y esperar mientras se hace (dos veces — primero escribirlo en el swap, luego reubicarlo al sistema de archivos). Es conveniente limitar la cantidad de RAM que utilizará el sistema a través de una variable en [.filename]#/boot/loader.conf#: + +[.programlisting] +.... + hw.physmem="256M" +.... + +Si los kernel panics son frecuentes y los sistemas de archivos son grandes (o simplemente no confías en softupdates + fsck en segundo plano), es aconsejable desactivar fsck en segundo plano mediante la siguiente variable en [.filename]#/etc/rc.conf#: + +[.programlisting] +.... + background_fsck="NO" +.... + +De esta forma, los sistemas de archivos siempre serán verificados cuando sea necesario. Ten en cuenta que con fsck en segundo plano, podría producirse un nuevo kernel panic mientras comprueba los discos. Una vez más, la forma más segura es no tener muchos sistemas de archivos sino utilizar otro ordenador como servidor NFS. + +[[prelim-starting]] +=== Empezando el proyecto + +Con el fin de crear una nueva clase GEOM, se debe crear un subdirectorio vacío bajo un directorio arbitrario que sea accesible por el usuario. No es necesario crear el directorio del módulo en [.filename]#/usr/src#. + +[[prelim-makefile]] +=== El Makefile + +Es una buena práctica crear [.filename]#Makefiles# para cada proyecto de programación que no sea trivial, lo que incluye obviamente módulos del kernel. + +Crear el archivo [.filename]#Makefile# es sencillo gracias a un extenso conjunto de rutinas de ayuda proporcionadas por el sistema. En resumen, aquí hay un ejemplo de cómo es un [.filename]#Makefile# mínimo para un módulo del kernel: + +[.programlisting] +.... +SRCS=g_journal.c +KMOD=geom_journal + +.include +.... + +Este [.filename]#Makefile# (con nombres de archivo modificados) funcionará para cualquier módulo del kernel, y una clase GEOM puede residir en un solo módulo del kernel. Si se necesita más de un archivo, añadelo a la variable `SRCS`, separado con espacios en blanco de los otros nombres de archivos. + +[[kernelprog]] +== Programación del kernel de FreeBSD + +[[kernelprog-memalloc]] +=== Asignación de memoria + +Lee man:malloc[9]. La asignación básica de memoria sólo es un poco diferente de su equivalente en espacio de usuario. Lo más llamativo es que `malloc`() y `free`() aceptan parámetros adicionales como se describe en la página del manual. + +Se tiene que declarar un "malloc type" en la sección de declaraciones de un fichero de código de este modo: + +[.programlisting] +.... + static MALLOC_DEFINE(M_GJOURNAL, "gjournal data", "GEOM_JOURNAL Data"); +.... + +Para usar esta macro se tienen que incluir los ficheros de cabecera [.filename]#sys/param.h#, [.filename]#sys/kernel.h# y [.filename]#sys/malloc.h#. + +Hay otro mecanismo para reservar memoria, el UMA (Universal Memory Allocator). Lee man:uma[9] para obtener detalles, pero es un tipo especial de gestor que se utiliza principalmente para acelerar la reserva de listas compuestas de elementos del mismo tamaño (por ejemplo, arrays dinámicos de estructuras). + +[[kernelprog-lists]] +=== Listas y colas + +Lee man:queue[3]. Hay MUCHOS casos en los que se necesita mantener una lista de cosas. Afortunadamente esta estructura de datos se implementa (de muchas formas) mediante macros de C incluidas en el sistema. El tipo de lista más utilizado es TAILQ porque es el más flexible. También es el que requiere más memoria (sus elementos están doblemente enlazados) y también el más lento (aunque la variación de velocidad está en el orden de varias instrucciones de CPU, así que esto no se debería tomar en serio). + +Si la velocidad de recuperación de los datos es importante, consulta man:tree[3] y man:hashinit[9]. + +[[kernelprog-bios]] +=== BIOs + +La estructura `bio` se utiliza para todas las operaciones de Entrada/Salida que tengan que ver con GEOM. Básicamente contiene información acerca de qué dispositivo ('provider') debería satisfacer la petición, el tipo de petición, el desplazamiento, la longitud, el puntero al buffer, y un montón de flags y campos "específicos de usuario" que pueden ayudar a implementar varios hacks. + +Lo importante aquí es que los `bio` se manejan de forma asíncrona. Esto quiere decir que en la mayor parte del código no hay un análogo a las llamadas man:read[2] y man:write[2] de espacio de usuario que no retornan hasta que la petición ha terminado. En su lugar se utiliza una función proporcionada por el desarrollador que es invocada como una notificación cuando la solicitud se ha completado (o ha terminado en error). + +El modelo asíncrono de programación (también llamado orientado a eventos, o "event-driven") es algo más difícil que el modo imperativo que se usa mucho más en espacio de usuario (al menos lleva un tiempo acostumbrarse). En algunos casos se pueden usar las rutinas de soporte `g_write_data`() y `g_read_data`() pero __no siempre__. En concreto, no se pueden usar cuando se está bloqueando en un mutex; por ejemplo, el mutex para la topología de GEOM o el mutex interno que se adquiere en las funciones `.start`() y `.stop`(). + +[[geom]] +== Programación GEOM + +[[geom-ggate]] +=== Ggate + +Si no se necesita el máximo rendimiento, una forma mucho más sencilla de realizar una transformación de datos es implementarla en el espacio de usuario a través del servicio ggate (GEOM gate). Desafortunadamente, no hay una manera fácil de convertir o incluso compartir código entre las dos aproximaciones. + +[[geom-class]] +=== Clase GEOM + +Las clases GEOM son transformaciones sobre los datos. Estas transformaciones se pueden combinar en forma de árbol. Las instancias de las clases GEOM se llaman __geoms__. + +Cada clase GEOM tiene varios "métodos de clase" que son invocados cuando no se dispone de una instancia geom (o simplemente no están ligadas a una única instancia): + +* `.init` se llama cuando GEOM se entera de una nueva clase GEOM (cuando se carga el módulo del kernel.) +* `.fini` se llama cuando GEOM abandona la clase (cuando se descarga el módulo) +* A continuación se llama a `.taste`, una vez por cada proveedor que el sistema tenga disponible. Si corresponde, esta función generalmente creará e iniciará una instancia geom. +* `.destroy_geom` se llama cuando se debe desmantelar el geom +* `.ctlconf` se invoca cuando el usuario solicita la reconfiguración de un geom existente + +También se definen las funciones de eventos GEOM, que se copiarán en la instancia de geom. + +El campo `.geom` en la estructura `g_class` es una lista (LIST) de los geoms instanciados a partir de la clase. + +Estas funciones son llamadas desde el hilo del kernel g_event. + +[[geom-softc]] +=== Softc + +El nombre "softc" es un término heredado para"driver private data" (datos privados del controlador). El nombre probablemente proviene del término arcaico "software control block" (bloque de control software). En GEOM, es una estructura (para ser más precisos: un puntero a una estructura) que se puede adjuntar a una instancia de geom para mantener cualquier información que sea privada para dicha instancia. La mayoría de las clases de GEOM tienen los siguientes elementos: + +* `struct g_provider *provider` : El "provider" que instancia este geom +* `uint16_t n_disks` : Número de consumidores que consume este geom +* `struct g_consumer \**disks` : Array de `struct g_consumer*`. (No es posible utilizar un sólo nivel de indirección porque los struct g_consumer* los crea GEOM en nuestro nombre). + +La estructura `softc` contiene el estado completo de la instancia geom. Cada instancia geom tiene su propio softc. + +[[geom-metadata]] +=== Metadatos + +El formato de los metadatos es más o menos dependiente de la clase, pero DEBE comenzar por: + +* Un buffer de 16 bytes para la firma terminada en null (normalmente el nombre de la clase) +* ID de la versión del tipo uint32 + +Se supone que las clases de geom saben cómo manejar los metadatos con ID de versión menores que los suyos. + +Los metadatos se encuentran en el último sector del proveedor (y, por lo tanto, deben encajar en él). + +(Todo depende de la implementación, pero todo el código existente funciona así, y es compatible con las bibliotecas.) + +[[geom-creating]] +=== Etiquetar/crear un GEOM + +La secuencia de eventos es: + +* El usuario invoca la utilidad man:geom[8] (o alguno de sus amigos que están enlazados) +* la utilidad averigua qué clase geom se supone que tiene que manejar y busca la librería [.filename]#geom_CLASSNAME.so# (que está normalmente en [.filename]#/lib/geom#). +* usa man:dlopen[3] para cargar la librería y extrae las definiciones de los parámetros de línea de comandos y de las funciones de apoyo. + +En el caso de crear/etiquetar un nuevo geom, esto es lo que sucede: + +* man:geom[8] busca el comando (normalmente `label`) en los argumentos de línea de comando y llama a la función de apoyo. +* La función auxiliar comprueba los parámetros y recopila los metadatos, que procede a escribir a todos los proveedores interesados. +* Esto "echa a perder" los geoms existentes (si los hubiera) e inicializa una nueva ronda de "pruebas" de los proveedores. La clase geom reconoce los metadatos y levanta el geom. + +(La secuencia de eventos anterior depende de la implementación, pero todo el código existente funciona así, y es compatible con las bibliotecas.) + +[[geom-command]] +=== Estructura del comando GEOM + +La librería de apoyo [.filename]#geom_CLASSNAME.so# exporta la estructura `class_commands` que es un array de elementos de tipo `struct g_command`. Los comandos tienen un formato uniforme que se parece a: + +[.programlisting] +.... + verb [-options] geomname [other] +.... + +Los verbos comunes son: + +* label — para escribir metadatos en los dispositivos para que puedan ser reconocidos en la prueba y creados en geoms +* destroy — para destruir los metadatos, de forma que se destruyen los geoms + +Las opciones comunes son: + +* `-v` : sé verboso +* `-f` : forzar + +Muchas acciones, como etiquetar y destruir los metadatos, se pueden hacer en espacio de usuario. Para esto, `struct g_command` proporciona el campo `gc_func` al que se puede asignar una función (en el mismo [.filename]#.so#) que será llamada para procesar un verbo. Si `gc_func` es NULL, el comando se pasará al módulo del kernel, a la función `.ctlreq` de la clase geom. + +[[geom-geoms]] +=== Geoms + +Los geoms son instancias de clases GEOM. Tienen datos internos (una estructura softc) y algunas funciones con las que responden a eventos externos. + +Las funciones del evento son: + +* `.access` : calcula permisos (read/write/exclusive) +* `.dumpconf` : devuelve información sobre el geom en formato XML +* `.orphan` : llamada cuando algún proveedor subyacente se desconecta +* `.spoiled` : llamada cuando se escribe en algún proveedor subyacente +* `.start` : maneja E/S (I/O) + +Estas funciones se llaman desde el hilo `g_down` del kernel y no puede haber inactividad en este contexto, (consulta la definición de inactividad en otra parte) lo que limita un poco lo que se puede hacer, pero obliga a que el manejo sea rápido. + +De estas funciones, la más importante para realizar un trabajo útil real es la función `.start`() , que se llama cuando una solicitud BIO llega a un proveedor administrado por una instancia de la clase geom. + +[[geom-threads]] +=== Hilos de GEOM + +Hay tres hilos del kernel creados y ejecutados por el framework GEOM: + +* `g_down` : Maneja las peticiones que vienen de entidades de nivel superior (como una petición de espacio de usuario) hacia los dispositivos físicos +* `g_up` : Maneja respuestas de los controladores de dispositivos a las peticiones hechas por entidades de nivel superior +* `g_event` : Maneja los demás casos: creación de instancias geom, contadores de acceso, eventos "spoil", etc. + +Cuando un proceso de usuario realiza una petición de tipo "lee el dato X en el offset Y de un fichero", esto es lo que sucede: + +* El sistema de archivos convierte la solicitud en una instancia de struct bio y lo transmite al subsistema GEOM. Sabe qué instancia geom debería encargarse porque los sistemas de archivos se alojan directamente en una instancia geom. +* La solicitud termina como una llamada a la función `.start`() realizada en el hilo g_down y llega a la instancia de geom de nivel superior. +* Esta instancia de nivel superior (por ejemplo el particionador) determina que la petición se debería dirigir a una instancia de nivel inferior (por ejemplo el controlador del disco). Hace una copia de la petición bio (¡las peticiones bio _SIEMPRE_ se tienen que copiar entre instancias, con `g_clone_bio`()!), modifica los campos para el offset de los datos y el proveedor objetivo y ejecuta la copia con `g_io_request`() +* El controlador de disco también obtiene la petición bio al llamar a la función `.start`() del hilo `g_down`. Habla con el hardware, obtiene los datos y llama a `g_io_deliver`() en el bio. +* Ahora, la notificación de bio completada "sube" en el hilo `g_up`. Primero se llama a `.done`() del particionador en el hilo `g_up`, usa la información almacenada en el bio para liberar la estructura `bio` clonada (con `g_destroy_bio`()) y llama a `g_io_deliver`() en la petición original. +* El sistema de archivos obtiene los datos y los transfiere al espacio de usuario. + +Consulta la página de manual man:g_bio[9] para obtener información sobre cómo se pasan los datos de un lado para otro en la estructura `bio` (en particular date cuenta cómo se manejan los campos `bio_parent` y `bio_children`). + +Una característica importante es que: __NO PUEDE HABER HILOS G_UP Y G_DOWN QUE SE VAYAN A DORMIR__. Esto significa que en esos hilos no se puede hacer ninguna de las siguientes cosas (la lista por supuesto no está completa, es sólo informativa): + +* Llamadas a `msleep`() y `tsleep`(), evidentemente. +* Llamadas a `g_write_data`() y `g_read_data`(), porque estas duermen entre el paso de datos hacia los consumidores y la vuelta. +* Esperar por la E/S. +* Llamadas a man:malloc[9] y `uma_zalloc`() con el flag `M_WAITOK` establecido +* sx y otros sleepable locks + +Esta restricción está aquí para impedir que el código GEOM obstruya la ruta de las solicitudes de E/S, ya que el dormir no tiene limite de tiempo y puede no haber garantías sobre cuánto tiempo tardará (también hay algunas otras razones más técnicas). También significa que no hay mucho que se pueda hacer en estos hilos; por ejemplo, prácticamente cualquier cosa compleja requiere asignación de memoria. Afortunadamente, hay una salida: crear hilos adicionales en el kernel. + +[[geom-kernelthreads]] +=== Hilos del kernel para usar en el código GEOM + +Los hilos del kernel se crean con la función man:kthread_create[9] y se comportan de una forma similar a los hilos en espacio de usuario, sólo que no pueden volver al llamante para indicarles que han terminado sino que tienen que invocar man:kthread_exit[9]. + +En el código GEOM, el uso habitual de los hilos es para descargar el procesamiento de peticiones del hilo `g_down`(la función `.start`()). Estos hilos parecen "manejadores de eventos": tienen vinculada una lista de eventos asociados a ellos (en los cuales los eventos pueden publicarse mediante varias funciones en varios hilos, por lo que deben estar protegidos por un mutex), toma los eventos de la lista, uno por uno, y los procesa en una gran instrucción `switch`(). + +La principal ventaja de utilizar un hilo para manejar las solicitudes de E/S es que pueden dormir (sleep) cuando sea necesario. Ahora, esto suena bien, pero se debe pensar cuidadosamente. Dormir (sleeping) es bueno y muy conveniente, pero puede ser muy efectivo destruyendo el rendimiento de la transformación de geom. Las clases extremadamente sensibles al rendimiento probablemente deberían hacer todo el trabajo en la llamada a la función `.start`(), teniendo mucho cuidado de manejar los errores de falta de memoria y similares. + +El otro beneficio de tener un hilo manejador de eventos como este es serializar en un sólo hilo todas las peticiones y respuestas que vienen de los distintos hilos de geom. Esto también es muy cómodo pero puede ser lento. En la mayoría de los casos, el manejo de las peticiones de `.done`() se puede dejar en manos del hilo `g_up`. + +Los mutex en el kernel de FreeBSD (consulta man:mutex[9]) tienen una característica distintiva respecto de sus primos en espacio de usuario - el código no puede dormir mientras se tiene un mutex cogido. Si el código necesita dormir a menudo, los locks man:sx[9] podrían ser más apropiados. Por otro lado, si haces casi todo en un solo hilo, podrías no necesitar mutex en absoluto. diff --git a/documentation/content/es/articles/geom-class/_index.po b/documentation/content/es/articles/geom-class/_index.po new file mode 100644 index 0000000000..918425f609 --- /dev/null +++ b/documentation/content/es/articles/geom-class/_index.po @@ -0,0 +1,1396 @@ +# SOME DESCRIPTIVE TITLE +# Copyright (C) YEAR The FreeBSD Project +# This file is distributed under the same license as the FreeBSD Documentation package. +# Fernando Apesteguía , 2021, 2022. +msgid "" +msgstr "" +"Project-Id-Version: FreeBSD Documentation VERSION\n" +"POT-Creation-Date: 2022-02-01 09:21-0300\n" +"PO-Revision-Date: 2022-08-24 14:08+0000\n" +"Last-Translator: Fernando Apesteguía \n" +"Language-Team: Spanish \n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.10.1\n" + +#. type: YAML Front Matter: description +#: documentation/content/en/articles/geom-class/_index.adoc:1 +#, no-wrap +msgid "A guide to GEOM internals, and writing your own GEOM class" +msgstr "" +"Una guía sobre los detalles de GEOM y cómo escribir tu propia clase GEOM" + +#. type: Title = +#: documentation/content/en/articles/geom-class/_index.adoc:1 +#: documentation/content/en/articles/geom-class/_index.adoc:11 +#, no-wrap +msgid "Writing a GEOM Class" +msgstr "Escribiendo una clase GEOM" + +#. type: Plain text +#: documentation/content/en/articles/geom-class/_index.adoc:44 +msgid "Abstract" +msgstr "Resumen" + +#. type: Plain text +#: documentation/content/en/articles/geom-class/_index.adoc:47 +msgid "" +"This text documents some starting points in developing GEOM classes, and " +"kernel modules in general. It is assumed that the reader is familiar with C " +"userland programming." +msgstr "" +"Este texto documenta algunos puntos de partida en el desarrollo de clases " +"GEOM y módulos del kernel en general. Se asume que el lector está " +"familiarizado con la programación en C en modo usuario." + +#. type: Plain text +#: documentation/content/en/articles/geom-class/_index.adoc:49 +msgid "'''" +msgstr "'''" + +#. type: Title == +#: documentation/content/en/articles/geom-class/_index.adoc:53 +#, no-wrap +msgid "Introduction" +msgstr "Introducción" + +#. type: Title === +#: documentation/content/en/articles/geom-class/_index.adoc:56 +#, no-wrap +msgid "Documentation" +msgstr "Documentación" + +#. type: Plain text +#: documentation/content/en/articles/geom-class/_index.adoc:60 +msgid "" +"Documentation on kernel programming is scarce - it is one of few areas where " +"there is nearly nothing in the way of friendly tutorials, and the phrase " +"\"use the source!\" really holds true. However, there are some bits and " +"pieces (some of them seriously outdated) floating around that should be " +"studied before beginning to code:" +msgstr "" +"La documentación sobre la programación del kernel es escasa - es una de las " +"pocas áreas donde casi no hay tutoriales amigables, y la frase, \"¡usa el " +"código fuente!\", realmente es cierta. Sin embargo, hay algunos trozos (" +"algunos de ellos muy desactualizados) flotando alrededor que deben " +"estudiarse antes de comenzar a programar:" + +#. type: Plain text +#: documentation/content/en/articles/geom-class/_index.adoc:62 +msgid "" +"The extref:{developers-handbook}[FreeBSD Developer's Handbook] - part of the " +"documentation project, it does not contain anything specific to kernel " +"programming, but rather some general useful information." +msgstr "" +"El extref:{developers-handbook}[FreeBSD Developer's Handbook] - parte del " +"proyecto de documentación, no contiene nada específico a la programación del " +"kernel sino más bien algo de información útil en general." + +#. type: Plain text +#: documentation/content/en/articles/geom-class/_index.adoc:63 +msgid "" +"The extref:{arch-handbook}[FreeBSD Architecture Handbook] - also from the " +"documentation project, contains descriptions of several low-level facilities " +"and procedures. The most important chapter is 13, extref:{arch-handbook}" +"[Writing FreeBSD device drivers, driverbasics]." +msgstr "" +"El extref:{arch-handbook}[FreeBSD Architecture Handbook] - también parte del " +"proyecto de documentación, contiene descripciones de varios servicios y " +"procedimientos de bajo nivel. El capítulo más importante es el 13, extref" +":{arch-handbook}[Writing FreeBSD device drivers, driverbasics]." + +#. type: Plain text +#: documentation/content/en/articles/geom-class/_index.adoc:64 +msgid "" +"The Blueprints section of http://www.freebsddiary.org[FreeBSD Diary] web " +"site - contains several interesting articles on kernel facilities." +msgstr "" +"La sección Blueprints del sitio web http://www.freebsddiary.org[FreeBSD " +"Diary] - contiene varios artículos interesantes sobre servicios del kernel." + +#. type: Plain text +#: documentation/content/en/articles/geom-class/_index.adoc:65 +msgid "" +"The man pages in section 9 - for important documentation on kernel functions." +msgstr "" +"Las páginas del manual en la sección 9 — para documentación importante sobre " +"las funciones del kernel." + +#. type: Plain text +#: documentation/content/en/articles/geom-class/_index.adoc:66 +msgid "" +"The man:geom[4] man page and http://phk.freebsd.dk/pubs/[PHK's GEOM slides] " +"- for general introduction of the GEOM subsystem." +msgstr "" +"La página de manual man:geom[4] y http://phk.freebsd.dk/pubs/[PHK's GEOM " +"slides] - para una introducción general al subsistema GEOM." + +#. type: Plain text +#: documentation/content/en/articles/geom-class/_index.adoc:67 +msgid "" +"Man pages man:g_bio[9], man:g_event[9], man:g_data[9], man:g_geom[9], man:" +"g_provider[9], man:g_consumer[9], man:g_access[9] & others linked from " +"those, for documentation on specific functionalities." +msgstr "" +"Las páginas del manual man:g_bio[9], man:g_event[9], man:g_data[9], " +"man:g_geom[9], man:g_provider[9], man:g_consumer[9], man:g_access[9] y otras " +"enlazadas desde estas, para documentación sobre funcionalidades específicas." + +#. type: Plain text +#: documentation/content/en/articles/geom-class/_index.adoc:68 +msgid "" +"The man:style[9] man page - for documentation on the coding-style " +"conventions which must be followed for any code which is to be committed to " +"the FreeBSD tree." +msgstr "" +"La página del manual man:style[9] - para documentación sobre las " +"convenciones que debe seguir el estilo del código para todo aquel que se va " +"a añadir al árbol de FreeBSD." + +#. type: Title == +#: documentation/content/en/articles/geom-class/_index.adoc:70 +#, no-wrap +msgid "Preliminaries" +msgstr "Preliminares" + +#. type: Plain text +#: documentation/content/en/articles/geom-class/_index.adoc:77 +msgid "" +"The best way to do kernel development is to have (at least) two separate " +"computers. One of these would contain the development environment and " +"sources, and the other would be used to test the newly written code by " +"network-booting and network-mounting filesystems from the first one. This " +"way if the new code contains bugs and crashes the machine, it will not mess " +"up the sources (and other \"live\" data). The second system does not even " +"require a proper display. Instead, it could be connected with a serial " +"cable or KVM to the first one." +msgstr "" +"La mejor forma de hacer desarrollo del kernel es tener (al menos) dos " +"ordenadores separados. Uno de ellos debería de tener el entorno de " +"desarrollo y el código fuente, y el otro sería usado para probar el código " +"recién escrito, inicializando y montando su sistema de archivos a través de " +"la red desde el primer ordenador. De esta forma, si el nuevo código contiene " +"errores y bloquea el ordenador, esto no dañará el código fuente (ni ningún " +"otro dato que este ejecutándose en \"caliente\"). El segundo sistema ni " +"siquiera necesita un monitor adecuado. En su lugar, podría estar conectado " +"con un cable serie o KVM al primer ordenador." + +#. type: Plain text +#: documentation/content/en/articles/geom-class/_index.adoc:80 +msgid "" +"But, since not everybody has two or more computers handy, there are a few " +"things that can be done to prepare an otherwise \"live\" system for " +"developing kernel code. This setup is also applicable for developing in a " +"http://www.vmware.com/[VMWare] or http://www.qemu.org/[QEmu] virtual machine " +"(the next best thing after a dedicated development machine)." +msgstr "" +"Pero como no todo el mundo tiene dos o más ordenadores a mano, hay unas " +"pocas cosas que se pueden hacer para preparar un entorno \"en caliente\" " +"para desarrollar código del kernel. Esta configuración también se puede " +"aplicar para desarrollar en una máquina virtual http://www.vmware.com/" +"[VMWare] o http://www.qemu.org/[QEmu] (lo siguiente mejor después de tener " +"una máquina como entorno dedicado)." + +#. type: Title === +#: documentation/content/en/articles/geom-class/_index.adoc:82 +#, no-wrap +msgid "Modifying a System for Development" +msgstr "Modificar un sistema para el desarrollo" + +#. type: Plain text +#: documentation/content/en/articles/geom-class/_index.adoc:85 +msgid "" +"For any kernel programming a kernel with `INVARIANTS` enabled is a must-" +"have. So enter these in your kernel configuration file:" +msgstr "" +"Para cualquier programación del kernel, es obligatoria tener activada la " +"opción `INVARIANTS`. Así que añade estas líneas a tu archivo de " +"configuración del kernel:" + +#. type: delimited block . 4 +#: documentation/content/en/articles/geom-class/_index.adoc:90 +#, no-wrap +msgid "" +"options INVARIANT_SUPPORT\n" +"options INVARIANTS\n" +msgstr "" +"options INVARIANT_SUPPORT\n" +"options INVARIANTS\n" + +#. type: Plain text +#: documentation/content/en/articles/geom-class/_index.adoc:93 +msgid "" +"For more debugging you should also include WITNESS support, which will alert " +"you of mistakes in locking:" +msgstr "" +"Para tener un mayor nivel de depuración, también debes incluir el soporte de " +"WITNESS, que te advertirá sobre errores relacionados con los bloqueos:" + +#. type: delimited block . 4 +#: documentation/content/en/articles/geom-class/_index.adoc:98 +#, no-wrap +msgid "" +"options WITNESS_SUPPORT\n" +"options WITNESS\n" +msgstr "" +"options WITNESS_SUPPORT\n" +"options WITNESS\n" + +#. type: Plain text +#: documentation/content/en/articles/geom-class/_index.adoc:101 +msgid "For debugging crash dumps, a kernel with debug symbols is needed:" +msgstr "" +"Para depurar los volcados de memoria, se necesita un kernel con símbolos de " +"depuración:" + +#. type: delimited block . 4 +#: documentation/content/en/articles/geom-class/_index.adoc:105 +#, no-wrap +msgid " makeoptions DEBUG=-g\n" +msgstr " makeoptions DEBUG=-g\n" + +#. type: Plain text +#: documentation/content/en/articles/geom-class/_index.adoc:110 +msgid "" +"With the usual way of installing the kernel (`make installkernel`) the debug " +"kernel will not be automatically installed. It is called [.filename]#kernel." +"debug# and located in [.filename]#/usr/obj/usr/src/sys/KERNELNAME/#. For " +"convenience it should be copied to [.filename]#/boot/kernel/#." +msgstr "" +"Con la forma habitual de instalar el kernel (`make installkernel`) no se " +"instala el kernel de depuración de forma automática. Se llama [." +"filename]#kernel.debug# y se encuentra en [.filename]#/usr/obj/usr/src/sys/" +"KERNELNAME/#. Por comodidad se debería copiar a [.filename]#/boot/kernel/#." + +#. type: Plain text +#: documentation/content/en/articles/geom-class/_index.adoc:113 +msgid "" +"Another convenience is enabling the kernel debugger so you can examine a " +"kernel panic when it happens. For this, enter the following lines in your " +"kernel configuration file:" +msgstr "" +"Otra cosa útil es habilitar la depuración del kernel para que puedas " +"examinar el kernel panic cuando suceda. Para esto, introduce las siguientes " +"líneas en su archivo de configuración del kernel:" + +#. type: delimited block . 4 +#: documentation/content/en/articles/geom-class/_index.adoc:119 +#, no-wrap +msgid "" +"options KDB\n" +"options DDB\n" +"options KDB_TRACE\n" +msgstr "" +"options KDB\n" +"options DDB\n" +"options KDB_TRACE\n" + +#. type: Plain text +#: documentation/content/en/articles/geom-class/_index.adoc:122 +msgid "" +"For this to work you might need to set a sysctl (if it is not on by default):" +msgstr "" +"Para que esto funcione, es posible que necesites establecer un sysctl (si no " +"está activado de forma predeterminada):" + +#. type: delimited block . 4 +#: documentation/content/en/articles/geom-class/_index.adoc:126 +#, no-wrap +msgid " debug.debugger_on_panic=1\n" +msgstr " debug.debugger_on_panic=1\n" + +#. type: Plain text +#: documentation/content/en/articles/geom-class/_index.adoc:134 +msgid "" +"Kernel panics will happen, so care should be taken with the filesystem " +"cache. In particular, having softupdates might mean the latest file version " +"could be lost if a panic occurs before it is committed to storage. " +"Disabling softupdates yields a great performance hit, and still does not " +"guarantee data consistency. Mounting filesystem with the \"sync\" option is " +"needed for that. For a compromise, the softupdates cache delays can be " +"shortened. There are three sysctl's that are useful for this (best to be " +"set in [.filename]#/etc/sysctl.conf#):" +msgstr "" +"Ocurrirán kernel panics, por lo que se debe tener cuidado con la cache del " +"sistema de archivos. En particular, tener habilitadas las softupdates puede " +"significar que la última versión del archivo podría perderse si se produce " +"un kernel panic antes de que se haya hecho commit al almacenamiento. " +"Deshabilitar las softupdates produce un gran impacto en el rendimiento, y no " +"garantiza la consistencia de los datos. Para eso es necesario montar el " +"sistema de archivos con la opción \"sync\". Como solución de compromiso, se " +"pueden acortar los tiempos de espera de la cache de softupdates. Hay tres " +"sysctls que son útiles para esto (lo mejor es establecerlas en [.filename]#/" +"etc/sysctl.conf#):" + +#. type: delimited block . 4 +#: documentation/content/en/articles/geom-class/_index.adoc:140 +#, no-wrap +msgid "" +"kern.filedelay=5\n" +"kern.dirdelay=4\n" +"kern.metadelay=3\n" +msgstr "" +"kern.filedelay=5\n" +"kern.dirdelay=4\n" +"kern.metadelay=3\n" + +#. type: Plain text +#: documentation/content/en/articles/geom-class/_index.adoc:143 +msgid "The numbers represent seconds." +msgstr "Los números representan segundos." + +#. type: Plain text +#: documentation/content/en/articles/geom-class/_index.adoc:151 +msgid "" +"For debugging kernel panics, kernel core dumps are required. Since a kernel " +"panic might make filesystems unusable, this crash dump is first written to a " +"raw partition. Usually, this is the swap partition. This partition must be " +"at least as large as the physical RAM in the machine. On the next boot, the " +"dump is copied to a regular file. This happens after filesystems are " +"checked and mounted, and before swap is enabled. This is controlled with " +"two [.filename]#/etc/rc.conf# variables:" +msgstr "" +"Para depurar los kernel panics, los volcados del kernel (core dumps) son " +"necesarios. Dado que un kernel panic podría inutilizar los sistemas de " +"archivos, este volcado de memoria se graba primero en una partición sin " +"formato (raw). Por lo general, ésta es la partición swap. Esta partición " +"debe ser al menos tan grande como la RAM física del ordenador. En el " +"siguiente arranque, el volcado se copia en un archivo normal. Esto sucede " +"después de que los sistemas de archivos se verifiquen y monten, y antes de " +"habilitar la swap. Este proceso se controla con dos variables en [." +"filename]#/etc/rc.conf#:" + +#. type: delimited block . 4 +#: documentation/content/en/articles/geom-class/_index.adoc:156 +#, no-wrap +msgid "" +"dumpdev=\"/dev/ad0s4b\"\n" +"dumpdir=\"/usr/core\n" +msgstr "" +"dumpdev=\"/dev/ad0s4b\"\n" +"dumpdir=\"/usr/core\n" + +#. type: Plain text +#: documentation/content/en/articles/geom-class/_index.adoc:159 +msgid "" +"The `dumpdev` variable specifies the swap partition and `dumpdir` tells the " +"system where in the filesystem to relocate the core dump on reboot." +msgstr "" +"La variable `dumpdev` especifica la partición swap y `dumpdir` le indica al " +"sistema dónde copiar el dore dump al reiniciar." + +#. type: Plain text +#: documentation/content/en/articles/geom-class/_index.adoc:162 +msgid "" +"Writing kernel core dumps is slow and takes a long time so if you have lots " +"of memory (>256M) and lots of panics it could be frustrating to sit and wait " +"while it is done (twice - first to write it to swap, then to relocate it to " +"filesystem). It is convenient then to limit the amount of RAM the system " +"will use via a [.filename]#/boot/loader.conf# tunable:" +msgstr "" +"Escribir volcados del kernel es lento y lleva mucho tiempo, por lo que si " +"tienes mucha memoria (>256M) y muchos kernel panics, puede ser frustrante " +"sentarse y esperar mientras se hace (dos veces — primero escribirlo en el " +"swap, luego reubicarlo al sistema de archivos). Es conveniente limitar la " +"cantidad de RAM que utilizará el sistema a través de una variable en [." +"filename]#/boot/loader.conf#:" + +#. type: delimited block . 4 +#: documentation/content/en/articles/geom-class/_index.adoc:166 +#, no-wrap +msgid " hw.physmem=\"256M\"\n" +msgstr " hw.physmem=\"256M\"\n" + +#. type: Plain text +#: documentation/content/en/articles/geom-class/_index.adoc:169 +msgid "" +"If the panics are frequent and filesystems large (or you simply do not trust " +"softupdates+background fsck) it is advisable to turn background fsck off via " +"[.filename]#/etc/rc.conf# variable:" +msgstr "" +"Si los kernel panics son frecuentes y los sistemas de archivos son grandes (" +"o simplemente no confías en softupdates + fsck en segundo plano), es " +"aconsejable desactivar fsck en segundo plano mediante la siguiente variable " +"en [.filename]#/etc/rc.conf#:" + +#. type: delimited block . 4 +#: documentation/content/en/articles/geom-class/_index.adoc:173 +#, no-wrap +msgid " background_fsck=\"NO\"\n" +msgstr " background_fsck=\"NO\"\n" + +#. type: Plain text +#: documentation/content/en/articles/geom-class/_index.adoc:178 +msgid "" +"This way, the filesystems will always get checked when needed. Note that " +"with background fsck, a new panic could happen while it is checking the " +"disks. Again, the safest way is not to have many local filesystems by using " +"another computer as an NFS server." +msgstr "" +"De esta forma, los sistemas de archivos siempre serán verificados cuando sea " +"necesario. Ten en cuenta que con fsck en segundo plano, podría producirse un " +"nuevo kernel panic mientras comprueba los discos. Una vez más, la forma más " +"segura es no tener muchos sistemas de archivos sino utilizar otro ordenador " +"como servidor NFS." + +#. type: Title === +#: documentation/content/en/articles/geom-class/_index.adoc:180 +#, no-wrap +msgid "Starting the Project" +msgstr "Empezando el proyecto" + +#. type: Plain text +#: documentation/content/en/articles/geom-class/_index.adoc:184 +msgid "" +"For the purpose of creating a new GEOM class, an empty subdirectory has to " +"be created under an arbitrary user-accessible directory. You do not have to " +"create the module directory under [.filename]#/usr/src#." +msgstr "" +"Con el fin de crear una nueva clase GEOM, se debe crear un subdirectorio " +"vacío bajo un directorio arbitrario que sea accesible por el usuario. No es " +"necesario crear el directorio del módulo en [.filename]#/usr/src#." + +#. type: Title === +#: documentation/content/en/articles/geom-class/_index.adoc:186 +#, no-wrap +msgid "The Makefile" +msgstr "El Makefile" + +#. type: Plain text +#: documentation/content/en/articles/geom-class/_index.adoc:189 +msgid "" +"It is good practice to create [.filename]#Makefiles# for every nontrivial " +"coding project, which of course includes kernel modules." +msgstr "" +"Es una buena práctica crear [.filename]#Makefiles# para cada proyecto de " +"programación que no sea trivial, lo que incluye obviamente módulos del " +"kernel." + +#. type: Plain text +#: documentation/content/en/articles/geom-class/_index.adoc:192 +msgid "" +"Creating the [.filename]#Makefile# is simple thanks to an extensive set of " +"helper routines provided by the system. In short, here is how a minimal [." +"filename]#Makefile# looks for a kernel module:" +msgstr "" +"Crear el archivo [.filename]#Makefile# es sencillo gracias a un extenso " +"conjunto de rutinas de ayuda proporcionadas por el sistema. En resumen, aquí " +"hay un ejemplo de cómo es un [.filename]#Makefile# mínimo para un módulo del " +"kernel:" + +#. type: delimited block . 4 +#: documentation/content/en/articles/geom-class/_index.adoc:197 +#, no-wrap +msgid "" +"SRCS=g_journal.c\n" +"KMOD=geom_journal\n" +msgstr "" +"SRCS=g_journal.c\n" +"KMOD=geom_journal\n" + +#. type: delimited block . 4 +#: documentation/content/en/articles/geom-class/_index.adoc:199 +#, no-wrap +msgid ".include \n" +msgstr ".include \n" + +#. type: Plain text +#: documentation/content/en/articles/geom-class/_index.adoc:203 +msgid "" +"This [.filename]#Makefile# (with changed filenames) will do for any kernel " +"module, and a GEOM class can reside in just one kernel module. If more than " +"one file is required, list it in the `SRCS` variable, separated with " +"whitespace from other filenames." +msgstr "" +"Este [.filename]#Makefile# (con nombres de archivo modificados) funcionará " +"para cualquier módulo del kernel, y una clase GEOM puede residir en un solo " +"módulo del kernel. Si se necesita más de un archivo, añadelo a la variable " +"`SRCS`, separado con espacios en blanco de los otros nombres de archivos." + +#. type: Title == +#: documentation/content/en/articles/geom-class/_index.adoc:205 +#, no-wrap +msgid "On FreeBSD Kernel Programming" +msgstr "Programación del kernel de FreeBSD" + +#. type: Title === +#: documentation/content/en/articles/geom-class/_index.adoc:208 +#, no-wrap +msgid "Memory Allocation" +msgstr "Asignación de memoria" + +#. type: Plain text +#: documentation/content/en/articles/geom-class/_index.adoc:213 +msgid "" +"See man:malloc[9]. Basic memory allocation is only slightly different than " +"its userland equivalent. Most notably, `malloc`() and `free`() accept " +"additional parameters as is described in the man page." +msgstr "" +"Lee man:malloc[9]. La asignación básica de memoria sólo es un poco diferente " +"de su equivalente en espacio de usuario. Lo más llamativo es que `malloc`() " +"y `free`() aceptan parámetros adicionales como se describe en la página del " +"manual." + +#. type: Plain text +#: documentation/content/en/articles/geom-class/_index.adoc:215 +msgid "" +"A \"malloc type\" must be declared in the declaration section of a source " +"file, like this:" +msgstr "" +"Se tiene que declarar un \"malloc type\" en la sección de declaraciones de " +"un fichero de código de este modo:" + +#. type: delimited block . 4 +#: documentation/content/en/articles/geom-class/_index.adoc:219 +#, no-wrap +msgid " static MALLOC_DEFINE(M_GJOURNAL, \"gjournal data\", \"GEOM_JOURNAL Data\");\n" +msgstr "" +" static MALLOC_DEFINE(M_GJOURNAL, \"gjournal data\", \"GEOM_JOURNAL Data\");" +"\n" + +#. type: Plain text +#: documentation/content/en/articles/geom-class/_index.adoc:222 +msgid "" +"To use this macro, [.filename]#sys/param.h#, [.filename]#sys/kernel.h# and [." +"filename]#sys/malloc.h# headers must be included." +msgstr "" +"Para usar esta macro se tienen que incluir los ficheros de cabecera [." +"filename]#sys/param.h#, [.filename]#sys/kernel.h# y [.filename]#sys/malloc." +"h#." + +#. type: Plain text +#: documentation/content/en/articles/geom-class/_index.adoc:225 +msgid "" +"There is another mechanism for allocating memory, the UMA (Universal Memory " +"Allocator). See man:uma[9] for details, but it is a special type of " +"allocator mainly used for speedy allocation of lists comprised of same-sized " +"items (for example, dynamic arrays of structs)." +msgstr "" +"Hay otro mecanismo para reservar memoria, el UMA (Universal Memory Allocator)" +". Lee man:uma[9] para obtener detalles, pero es un tipo especial de gestor " +"que se utiliza principalmente para acelerar la reserva de listas compuestas " +"de elementos del mismo tamaño (por ejemplo, arrays dinámicos de estructuras)." + +#. type: Title === +#: documentation/content/en/articles/geom-class/_index.adoc:227 +#, no-wrap +msgid "Lists and Queues" +msgstr "Listas y colas" + +#. type: Plain text +#: documentation/content/en/articles/geom-class/_index.adoc:234 +msgid "" +"See man:queue[3]. There are a LOT of cases when a list of things needs to " +"be maintained. Fortunately, this data structure is implemented (in several " +"ways) by C macros included in the system. The most used list type is TAILQ " +"because it is the most flexible. It is also the one with largest memory " +"requirements (its elements are doubly-linked) and also the slowest (although " +"the speed variation is on the order of several CPU instructions more, so it " +"should not be taken seriously)." +msgstr "" +"Lee man:queue[3]. Hay MUCHOS casos en los que se necesita mantener una lista " +"de cosas. Afortunadamente esta estructura de datos se implementa (de muchas " +"formas) mediante macros de C incluidas en el sistema. El tipo de lista más " +"utilizado es TAILQ porque es el más flexible. También es el que requiere más " +"memoria (sus elementos están doblemente enlazados) y también el más lento (" +"aunque la variación de velocidad está en el orden de varias instrucciones de " +"CPU, así que esto no se debería tomar en serio)." + +#. type: Plain text +#: documentation/content/en/articles/geom-class/_index.adoc:236 +msgid "" +"If data retrieval speed is very important, see man:tree[3] and man:" +"hashinit[9]." +msgstr "" +"Si la velocidad de recuperación de los datos es importante, consulta " +"man:tree[3] y man:hashinit[9]." + +#. type: Title === +#: documentation/content/en/articles/geom-class/_index.adoc:238 +#, no-wrap +msgid "BIOs" +msgstr "BIOs" + +#. type: Plain text +#: documentation/content/en/articles/geom-class/_index.adoc:242 +msgid "" +"Structure `bio` is used for any and all Input/Output operations concerning " +"GEOM. It basically contains information about what device ('provider') " +"should satisfy the request, request type, offset, length, pointer to a " +"buffer, and a bunch of \"user-specific\" flags and fields that can help " +"implement various hacks." +msgstr "" +"La estructura `bio` se utiliza para todas las operaciones de Entrada/Salida " +"que tengan que ver con GEOM. Básicamente contiene información acerca de qué " +"dispositivo ('provider') debería satisfacer la petición, el tipo de " +"petición, el desplazamiento, la longitud, el puntero al buffer, y un montón " +"de flags y campos \"específicos de usuario\" que pueden ayudar a implementar " +"varios hacks." + +#. type: Plain text +#: documentation/content/en/articles/geom-class/_index.adoc:246 +msgid "" +"The important thing here is that ``bio``s are handled asynchronously. That " +"means that, in most parts of the code, there is no analogue to userland's " +"man:read[2] and man:write[2] calls that do not return until a request is " +"done. Rather, a developer-supplied function is called as a notification " +"when the request gets completed (or results in error)." +msgstr "" +"Lo importante aquí es que los `bio` se manejan de forma asíncrona. Esto " +"quiere decir que en la mayor parte del código no hay un análogo a las " +"llamadas man:read[2] y man:write[2] de espacio de usuario que no retornan " +"hasta que la petición ha terminado. En su lugar se utiliza una función " +"proporcionada por el desarrollador que es invocada como una notificación " +"cuando la solicitud se ha completado (o ha terminado en error)." + +#. type: Plain text +#: documentation/content/en/articles/geom-class/_index.adoc:250 +msgid "" +"The asynchronous programming model (also called \"event-driven\") is " +"somewhat harder than the much more used imperative one used in userland (at " +"least it takes a while to get used to it). In some cases the helper " +"routines `g_write_data`() and `g_read_data`() can be used, but __not " +"always__. In particular, they cannot be used when a mutex is held; for " +"example, the GEOM topology mutex or the internal mutex held during the `." +"start`() and `.stop`() functions." +msgstr "" +"El modelo asíncrono de programación (también llamado orientado a eventos, o " +"\"event-driven\") es algo más difícil que el modo imperativo que se usa " +"mucho más en espacio de usuario (al menos lleva un tiempo acostumbrarse). En " +"algunos casos se pueden usar las rutinas de soporte `g_write_data`() y " +"`g_read_data`() pero __no siempre__. En concreto, no se pueden usar cuando " +"se está bloqueando en un mutex; por ejemplo, el mutex para la topología de " +"GEOM o el mutex interno que se adquiere en las funciones `.start`() y `." +"stop`()." + +#. type: Title == +#: documentation/content/en/articles/geom-class/_index.adoc:252 +#, no-wrap +msgid "On GEOM Programming" +msgstr "Programación GEOM" + +#. type: Title === +#: documentation/content/en/articles/geom-class/_index.adoc:255 +#, no-wrap +msgid "Ggate" +msgstr "Ggate" + +#. type: Plain text +#: documentation/content/en/articles/geom-class/_index.adoc:259 +msgid "" +"If maximum performance is not needed, a much simpler way of making a data " +"transformation is to implement it in userland via the ggate (GEOM gate) " +"facility. Unfortunately, there is no easy way to convert between, or even " +"share code between the two approaches." +msgstr "" +"Si no se necesita el máximo rendimiento, una forma mucho más sencilla de " +"realizar una transformación de datos es implementarla en el espacio de " +"usuario a través del servicio ggate (GEOM gate). Desafortunadamente, no hay " +"una manera fácil de convertir o incluso compartir código entre las dos " +"aproximaciones." + +#. type: Title === +#: documentation/content/en/articles/geom-class/_index.adoc:261 +#, no-wrap +msgid "GEOM Class" +msgstr "Clase GEOM" + +#. type: Plain text +#: documentation/content/en/articles/geom-class/_index.adoc:266 +msgid "" +"GEOM classes are transformations on the data. These transformations can be " +"combined in a tree-like fashion. Instances of GEOM classes are called " +"__geoms__." +msgstr "" +"Las clases GEOM son transformaciones sobre los datos. Estas transformaciones " +"se pueden combinar en forma de árbol. Las instancias de las clases GEOM se " +"llaman __geoms__." + +#. type: Plain text +#: documentation/content/en/articles/geom-class/_index.adoc:268 +msgid "" +"Each GEOM class has several \"class methods\" that get called when there is " +"no geom instance available (or they are simply not bound to a single " +"instance):" +msgstr "" +"Cada clase GEOM tiene varios \"métodos de clase\" que son invocados cuando " +"no se dispone de una instancia geom (o simplemente no están ligadas a una " +"única instancia):" + +#. type: Plain text +#: documentation/content/en/articles/geom-class/_index.adoc:270 +msgid "" +"`.init` is called when GEOM becomes aware of a GEOM class (when the kernel " +"module gets loaded.)" +msgstr "" +"`.init` se llama cuando GEOM se entera de una nueva clase GEOM (cuando se " +"carga el módulo del kernel.)" + +#. type: Plain text +#: documentation/content/en/articles/geom-class/_index.adoc:271 +msgid "" +"`.fini` gets called when GEOM abandons the class (when the module gets " +"unloaded)" +msgstr "" +"`.fini` se llama cuando GEOM abandona la clase (cuando se descarga el módulo)" + +#. type: Plain text +#: documentation/content/en/articles/geom-class/_index.adoc:272 +msgid "" +"`.taste` is called next, once for each provider the system has available. If " +"applicable, this function will usually create and start a geom instance." +msgstr "" +"A continuación se llama a `.taste`, una vez por cada proveedor que el " +"sistema tenga disponible. Si corresponde, esta función generalmente creará e " +"iniciará una instancia geom." + +#. type: Plain text +#: documentation/content/en/articles/geom-class/_index.adoc:273 +msgid "`.destroy_geom` is called when the geom should be disbanded" +msgstr "`.destroy_geom` se llama cuando se debe desmantelar el geom" + +#. type: Plain text +#: documentation/content/en/articles/geom-class/_index.adoc:274 +msgid "" +"`.ctlconf` is called when user requests reconfiguration of existing geom" +msgstr "" +"`.ctlconf` se invoca cuando el usuario solicita la reconfiguración de un " +"geom existente" + +#. type: Plain text +#: documentation/content/en/articles/geom-class/_index.adoc:276 +msgid "" +"Also defined are the GEOM event functions, which will get copied to the geom " +"instance." +msgstr "" +"También se definen las funciones de eventos GEOM, que se copiarán en la " +"instancia de geom." + +#. type: Plain text +#: documentation/content/en/articles/geom-class/_index.adoc:278 +msgid "" +"Field `.geom` in the `g_class` structure is a LIST of geoms instantiated " +"from the class." +msgstr "" +"El campo `.geom` en la estructura `g_class` es una lista (LIST) de los geoms " +"instanciados a partir de la clase." + +#. type: Plain text +#: documentation/content/en/articles/geom-class/_index.adoc:280 +msgid "These functions are called from the g_event kernel thread." +msgstr "Estas funciones son llamadas desde el hilo del kernel g_event." + +#. type: Title === +#: documentation/content/en/articles/geom-class/_index.adoc:282 +#, no-wrap +msgid "Softc" +msgstr "Softc" + +#. type: Plain text +#: documentation/content/en/articles/geom-class/_index.adoc:288 +msgid "" +"The name \"softc\" is a legacy term for \"driver private data\". The name " +"most probably comes from the archaic term \"software control block\". In " +"GEOM, it is a structure (more precise: pointer to a structure) that can be " +"attached to a geom instance to hold whatever data is private to the geom " +"instance. Most GEOM classes have the following members:" +msgstr "" +"El nombre \"softc\" es un término heredado para\"driver private data\" (" +"datos privados del controlador). El nombre probablemente proviene del " +"término arcaico \"software control block\" (bloque de control software). En " +"GEOM, es una estructura (para ser más precisos: un puntero a una estructura) " +"que se puede adjuntar a una instancia de geom para mantener cualquier " +"información que sea privada para dicha instancia. La mayoría de las clases " +"de GEOM tienen los siguientes elementos:" + +#. type: Plain text +#: documentation/content/en/articles/geom-class/_index.adoc:290 +msgid "`struct g_provider *provider` : The \"provider\" this geom instantiates" +msgstr "`struct g_provider *provider` : El \"provider\" que instancia este geom" + +#. type: Plain text +#: documentation/content/en/articles/geom-class/_index.adoc:291 +msgid "`uint16_t n_disks` : Number of consumer this geom consumes" +msgstr "`uint16_t n_disks` : Número de consumidores que consume este geom" + +#. type: Plain text +#: documentation/content/en/articles/geom-class/_index.adoc:292 +msgid "" +"`struct g_consumer \\**disks` : Array of `struct g_consumer*`. (It is not " +"possible to use just single indirection because struct g_consumer* are " +"created on our behalf by GEOM)." +msgstr "" +"`struct g_consumer \\**disks` : Array de `struct g_consumer*`. (No es " +"posible utilizar un sólo nivel de indirección porque los struct g_consumer* " +"los crea GEOM en nuestro nombre)." + +#. type: Plain text +#: documentation/content/en/articles/geom-class/_index.adoc:295 +msgid "" +"The `softc` structure contains all the state of geom instance. Every geom " +"instance has its own softc." +msgstr "" +"La estructura `softc` contiene el estado completo de la instancia geom. Cada " +"instancia geom tiene su propio softc." + +#. type: Title === +#: documentation/content/en/articles/geom-class/_index.adoc:297 +#, no-wrap +msgid "Metadata" +msgstr "Metadatos" + +#. type: Plain text +#: documentation/content/en/articles/geom-class/_index.adoc:300 +msgid "" +"Format of metadata is more-or-less class-dependent, but MUST start with:" +msgstr "" +"El formato de los metadatos es más o menos dependiente de la clase, pero " +"DEBE comenzar por:" + +#. type: Plain text +#: documentation/content/en/articles/geom-class/_index.adoc:302 +msgid "16 byte buffer for null-terminated signature (usually the class name)" +msgstr "" +"Un buffer de 16 bytes para la firma terminada en null (normalmente el nombre " +"de la clase)" + +#. type: Plain text +#: documentation/content/en/articles/geom-class/_index.adoc:303 +msgid "uint32 version ID" +msgstr "ID de la versión del tipo uint32" + +#. type: Plain text +#: documentation/content/en/articles/geom-class/_index.adoc:305 +msgid "" +"It is assumed that geom classes know how to handle metadata with version " +"ID's lower than theirs." +msgstr "" +"Se supone que las clases de geom saben cómo manejar los metadatos con ID de " +"versión menores que los suyos." + +#. type: Plain text +#: documentation/content/en/articles/geom-class/_index.adoc:307 +msgid "" +"Metadata is located in the last sector of the provider (and thus must fit in " +"it)." +msgstr "" +"Los metadatos se encuentran en el último sector del proveedor (y, por lo " +"tanto, deben encajar en él)." + +#. type: Plain text +#: documentation/content/en/articles/geom-class/_index.adoc:309 +msgid "" +"(All this is implementation-dependent but all existing code works like that, " +"and it is supported by libraries.)" +msgstr "" +"(Todo depende de la implementación, pero todo el código existente funciona " +"así, y es compatible con las bibliotecas.)" + +#. type: Title === +#: documentation/content/en/articles/geom-class/_index.adoc:311 +#, no-wrap +msgid "Labeling/creating a GEOM" +msgstr "Etiquetar/crear un GEOM" + +#. type: Plain text +#: documentation/content/en/articles/geom-class/_index.adoc:314 +msgid "The sequence of events is:" +msgstr "La secuencia de eventos es:" + +#. type: Plain text +#: documentation/content/en/articles/geom-class/_index.adoc:316 +msgid "user calls man:geom[8] utility (or one of its hardlinked friends)" +msgstr "" +"El usuario invoca la utilidad man:geom[8] (o alguno de sus amigos que están " +"enlazados)" + +#. type: Plain text +#: documentation/content/en/articles/geom-class/_index.adoc:317 +msgid "" +"the utility figures out which geom class it is supposed to handle and " +"searches for [.filename]#geom_CLASSNAME.so# library (usually in [.filename]#/" +"lib/geom#)." +msgstr "" +"la utilidad averigua qué clase geom se supone que tiene que manejar y busca " +"la librería [.filename]#geom_CLASSNAME.so# (que está normalmente en [." +"filename]#/lib/geom#)." + +#. type: Plain text +#: documentation/content/en/articles/geom-class/_index.adoc:318 +msgid "" +"it man:dlopen[3]-s the library, extracts the definitions of command-line " +"parameters and helper functions." +msgstr "" +"usa man:dlopen[3] para cargar la librería y extrae las definiciones de los " +"parámetros de línea de comandos y de las funciones de apoyo." + +#. type: Plain text +#: documentation/content/en/articles/geom-class/_index.adoc:320 +msgid "In the case of creating/labeling a new geom, this is what happens:" +msgstr "En el caso de crear/etiquetar un nuevo geom, esto es lo que sucede:" + +#. type: Plain text +#: documentation/content/en/articles/geom-class/_index.adoc:322 +msgid "" +"man:geom[8] looks in the command-line argument for the command (usually " +"`label`), and calls a helper function." +msgstr "" +"man:geom[8] busca el comando (normalmente `label`) en los argumentos de " +"línea de comando y llama a la función de apoyo." + +#. type: Plain text +#: documentation/content/en/articles/geom-class/_index.adoc:323 +msgid "" +"The helper function checks parameters and gathers metadata, which it " +"proceeds to write to all concerned providers." +msgstr "" +"La función auxiliar comprueba los parámetros y recopila los metadatos, que " +"procede a escribir a todos los proveedores interesados." + +#. type: Plain text +#: documentation/content/en/articles/geom-class/_index.adoc:324 +msgid "" +"This \"spoils\" existing geoms (if any) and initializes a new round of " +"\"tasting\" of the providers. The intended geom class recognizes the " +"metadata and brings the geom up." +msgstr "" +"Esto \"echa a perder\" los geoms existentes (si los hubiera) e inicializa " +"una nueva ronda de \"pruebas\" de los proveedores. La clase geom reconoce " +"los metadatos y levanta el geom." + +#. type: Plain text +#: documentation/content/en/articles/geom-class/_index.adoc:326 +msgid "" +"(The above sequence of events is implementation-dependent but all existing " +"code works like that, and it is supported by libraries.)" +msgstr "" +"(La secuencia de eventos anterior depende de la implementación, pero todo el " +"código existente funciona así, y es compatible con las bibliotecas.)" + +#. type: Title === +#: documentation/content/en/articles/geom-class/_index.adoc:328 +#, no-wrap +msgid "GEOM Command Structure" +msgstr "Estructura del comando GEOM" + +#. type: Plain text +#: documentation/content/en/articles/geom-class/_index.adoc:332 +msgid "" +"The helper [.filename]#geom_CLASSNAME.so# library exports `class_commands` " +"structure, which is an array of `struct g_command` elements. Commands are " +"of uniform format and look like:" +msgstr "" +"La librería de apoyo [.filename]#geom_CLASSNAME.so# exporta la estructura " +"`class_commands` que es un array de elementos de tipo `struct g_command`. " +"Los comandos tienen un formato uniforme que se parece a:" + +#. type: delimited block . 4 +#: documentation/content/en/articles/geom-class/_index.adoc:336 +#, no-wrap +msgid " verb [-options] geomname [other]\n" +msgstr " verb [-options] geomname [other]\n" + +#. type: Plain text +#: documentation/content/en/articles/geom-class/_index.adoc:339 +msgid "Common verbs are:" +msgstr "Los verbos comunes son:" + +#. type: Plain text +#: documentation/content/en/articles/geom-class/_index.adoc:341 +msgid "" +"label - to write metadata to devices so they can be recognized at tasting " +"and brought up in geoms" +msgstr "" +"label — para escribir metadatos en los dispositivos para que puedan ser " +"reconocidos en la prueba y creados en geoms" + +#. type: Plain text +#: documentation/content/en/articles/geom-class/_index.adoc:342 +msgid "destroy - to destroy metadata, so the geoms get destroyed" +msgstr "" +"destroy — para destruir los metadatos, de forma que se destruyen los geoms" + +#. type: Plain text +#: documentation/content/en/articles/geom-class/_index.adoc:344 +msgid "Common options are:" +msgstr "Las opciones comunes son:" + +#. type: Plain text +#: documentation/content/en/articles/geom-class/_index.adoc:346 +msgid "`-v` : be verbose" +msgstr "`-v` : sé verboso" + +#. type: Plain text +#: documentation/content/en/articles/geom-class/_index.adoc:347 +msgid "`-f` : force" +msgstr "`-f` : forzar" + +#. type: Plain text +#: documentation/content/en/articles/geom-class/_index.adoc:351 +msgid "" +"Many actions, such as labeling and destroying metadata can be performed in " +"userland. For this, `struct g_command` provides field `gc_func` that can be " +"set to a function (in the same [.filename]#.so#) that will be called to " +"process a verb. If `gc_func` is NULL, the command will be passed to kernel " +"module, to `.ctlreq` function of the geom class." +msgstr "" +"Muchas acciones, como etiquetar y destruir los metadatos, se pueden hacer en " +"espacio de usuario. Para esto, `struct g_command` proporciona el campo " +"`gc_func` al que se puede asignar una función (en el mismo [.filename]#.so#) " +"que será llamada para procesar un verbo. Si `gc_func` es NULL, el comando se " +"pasará al módulo del kernel, a la función `.ctlreq` de la clase geom." + +#. type: Title === +#: documentation/content/en/articles/geom-class/_index.adoc:353 +#, no-wrap +msgid "Geoms" +msgstr "Geoms" + +#. type: Plain text +#: documentation/content/en/articles/geom-class/_index.adoc:357 +msgid "" +"Geoms are instances of GEOM classes. They have internal data (a softc " +"structure) and some functions with which they respond to external events." +msgstr "" +"Los geoms son instancias de clases GEOM. Tienen datos internos (una " +"estructura softc) y algunas funciones con las que responden a eventos " +"externos." + +#. type: Plain text +#: documentation/content/en/articles/geom-class/_index.adoc:359 +msgid "The event functions are:" +msgstr "Las funciones del evento son:" + +#. type: Plain text +#: documentation/content/en/articles/geom-class/_index.adoc:361 +msgid "`.access` : calculates permissions (read/write/exclusive)" +msgstr "`.access` : calcula permisos (read/write/exclusive)" + +#. type: Plain text +#: documentation/content/en/articles/geom-class/_index.adoc:362 +msgid "`.dumpconf` : returns XML-formatted information about the geom" +msgstr "`.dumpconf` : devuelve información sobre el geom en formato XML" + +#. type: Plain text +#: documentation/content/en/articles/geom-class/_index.adoc:363 +msgid "`.orphan` : called when some underlying provider gets disconnected" +msgstr "`.orphan` : llamada cuando algún proveedor subyacente se desconecta" + +#. type: Plain text +#: documentation/content/en/articles/geom-class/_index.adoc:364 +msgid "`.spoiled` : called when some underlying provider gets written to" +msgstr "`.spoiled` : llamada cuando se escribe en algún proveedor subyacente" + +#. type: Plain text +#: documentation/content/en/articles/geom-class/_index.adoc:365 +msgid "`.start` : handles I/O" +msgstr "`.start` : maneja E/S (I/O)" + +#. type: Plain text +#: documentation/content/en/articles/geom-class/_index.adoc:367 +msgid "" +"These functions are called from the `g_down` kernel thread and there can be " +"no sleeping in this context, (see definition of sleeping elsewhere) which " +"limits what can be done quite a bit, but forces the handling to be fast." +msgstr "" +"Estas funciones se llaman desde el hilo `g_down` del kernel y no puede haber " +"inactividad en este contexto, (consulta la definición de inactividad en otra " +"parte) lo que limita un poco lo que se puede hacer, pero obliga a que el " +"manejo sea rápido." + +#. type: Plain text +#: documentation/content/en/articles/geom-class/_index.adoc:369 +msgid "" +"Of these, the most important function for doing actual useful work is the `." +"start`() function, which is called when a BIO request arrives for a provider " +"managed by a instance of geom class." +msgstr "" +"De estas funciones, la más importante para realizar un trabajo útil real es " +"la función `.start`() , que se llama cuando una solicitud BIO llega a un " +"proveedor administrado por una instancia de la clase geom." + +#. type: Title === +#: documentation/content/en/articles/geom-class/_index.adoc:371 +#, no-wrap +msgid "GEOM Threads" +msgstr "Hilos de GEOM" + +#. type: Plain text +#: documentation/content/en/articles/geom-class/_index.adoc:374 +msgid "There are three kernel threads created and run by the GEOM framework:" +msgstr "Hay tres hilos del kernel creados y ejecutados por el framework GEOM:" + +#. type: Plain text +#: documentation/content/en/articles/geom-class/_index.adoc:376 +msgid "" +"`g_down` : Handles requests coming from high-level entities (such as a " +"userland request) on the way to physical devices" +msgstr "" +"`g_down` : Maneja las peticiones que vienen de entidades de nivel superior (" +"como una petición de espacio de usuario) hacia los dispositivos físicos" + +#. type: Plain text +#: documentation/content/en/articles/geom-class/_index.adoc:377 +msgid "" +"`g_up` : Handles responses from device drivers to requests made by higher-" +"level entities" +msgstr "" +"`g_up` : Maneja respuestas de los controladores de dispositivos a las " +"peticiones hechas por entidades de nivel superior" + +#. type: Plain text +#: documentation/content/en/articles/geom-class/_index.adoc:378 +msgid "" +"`g_event` : Handles all other cases: creation of geom instances, access " +"counting, \"spoil\" events, etc." +msgstr "" +"`g_event` : Maneja los demás casos: creación de instancias geom, contadores " +"de acceso, eventos \"spoil\", etc." + +#. type: Plain text +#: documentation/content/en/articles/geom-class/_index.adoc:380 +msgid "" +"When a user process issues \"read data X at offset Y of a file\" request, " +"this is what happens:" +msgstr "" +"Cuando un proceso de usuario realiza una petición de tipo \"lee el dato X en " +"el offset Y de un fichero\", esto es lo que sucede:" + +#. type: Plain text +#: documentation/content/en/articles/geom-class/_index.adoc:382 +msgid "" +"The filesystem converts the request into a struct bio instance and passes it " +"to the GEOM subsystem. It knows what geom instance should handle it because " +"filesystems are hosted directly on a geom instance." +msgstr "" +"El sistema de archivos convierte la solicitud en una instancia de struct bio " +"y lo transmite al subsistema GEOM. Sabe qué instancia geom debería " +"encargarse porque los sistemas de archivos se alojan directamente en una " +"instancia geom." + +#. type: Plain text +#: documentation/content/en/articles/geom-class/_index.adoc:383 +msgid "" +"The request ends up as a call to the `.start`() function made on the g_down " +"thread and reaches the top-level geom instance." +msgstr "" +"La solicitud termina como una llamada a la función `.start`() realizada en " +"el hilo g_down y llega a la instancia de geom de nivel superior." + +#. type: Plain text +#: documentation/content/en/articles/geom-class/_index.adoc:384 +msgid "" +"This top-level geom instance (for example the partition slicer) determines " +"that the request should be routed to a lower-level instance (for example the " +"disk driver). It makes a copy of the bio request (bio requests _ALWAYS_ need " +"to be copied between instances, with `g_clone_bio`()!), modifies the data " +"offset and target provider fields and executes the copy with `g_io_request`()" +msgstr "" +"Esta instancia de nivel superior (por ejemplo el particionador) determina " +"que la petición se debería dirigir a una instancia de nivel inferior (por " +"ejemplo el controlador del disco). Hace una copia de la petición bio (¡las " +"peticiones bio _SIEMPRE_ se tienen que copiar entre instancias, con " +"`g_clone_bio`()!), modifica los campos para el offset de los datos y el " +"proveedor objetivo y ejecuta la copia con `g_io_request`()" + +#. type: Plain text +#: documentation/content/en/articles/geom-class/_index.adoc:385 +msgid "" +"The disk driver gets the bio request also as a call to `.start`() on the " +"`g_down` thread. It talks to hardware, gets the data back, and calls " +"`g_io_deliver`() on the bio." +msgstr "" +"El controlador de disco también obtiene la petición bio al llamar a la " +"función `.start`() del hilo `g_down`. Habla con el hardware, obtiene los " +"datos y llama a `g_io_deliver`() en el bio." + +#. type: Plain text +#: documentation/content/en/articles/geom-class/_index.adoc:386 +msgid "" +"Now, the notification of bio completion \"bubbles up\" in the `g_up` thread. " +"First the partition slicer gets `.done`() called in the `g_up` thread, it " +"uses information stored in the bio to free the cloned `bio` structure (with " +"`g_destroy_bio`()) and calls `g_io_deliver`() on the original request." +msgstr "" +"Ahora, la notificación de bio completada \"sube\" en el hilo `g_up`. Primero " +"se llama a `.done`() del particionador en el hilo `g_up`, usa la información " +"almacenada en el bio para liberar la estructura `bio` clonada (con " +"`g_destroy_bio`()) y llama a `g_io_deliver`() en la petición original." + +#. type: Plain text +#: documentation/content/en/articles/geom-class/_index.adoc:387 +msgid "The filesystem gets the data and transfers it to userland." +msgstr "" +"El sistema de archivos obtiene los datos y los transfiere al espacio de " +"usuario." + +#. type: Plain text +#: documentation/content/en/articles/geom-class/_index.adoc:389 +msgid "" +"See man:g_bio[9] man page for information how the data is passed back and " +"forth in the `bio` structure (note in particular the `bio_parent` and " +"`bio_children` fields and how they are handled)." +msgstr "" +"Consulta la página de manual man:g_bio[9] para obtener información sobre " +"cómo se pasan los datos de un lado para otro en la estructura `bio` (en " +"particular date cuenta cómo se manejan los campos `bio_parent` y " +"`bio_children`)." + +#. type: Plain text +#: documentation/content/en/articles/geom-class/_index.adoc:392 +msgid "" +"One important feature is: __THERE CAN BE NO SLEEPING IN G_UP AND G_DOWN " +"THREADS__. This means that none of the following things can be done in " +"those threads (the list is of course not complete, but only informative):" +msgstr "" +"Una característica importante es que: __NO PUEDE HABER HILOS G_UP Y G_DOWN " +"QUE SE VAYAN A DORMIR__. Esto significa que en esos hilos no se puede hacer " +"ninguna de las siguientes cosas (la lista por supuesto no está completa, es " +"sólo informativa):" + +#. type: Plain text +#: documentation/content/en/articles/geom-class/_index.adoc:394 +msgid "Calls to `msleep`() and `tsleep`(), obviously." +msgstr "Llamadas a `msleep`() y `tsleep`(), evidentemente." + +#. type: Plain text +#: documentation/content/en/articles/geom-class/_index.adoc:395 +msgid "" +"Calls to `g_write_data`() and `g_read_data`(), because these sleep between " +"passing the data to consumers and returning." +msgstr "" +"Llamadas a `g_write_data`() y `g_read_data`(), porque estas duermen entre el " +"paso de datos hacia los consumidores y la vuelta." + +#. type: Plain text +#: documentation/content/en/articles/geom-class/_index.adoc:396 +msgid "Waiting for I/O." +msgstr "Esperar por la E/S." + +#. type: Plain text +#: documentation/content/en/articles/geom-class/_index.adoc:397 +msgid "Calls to man:malloc[9] and `uma_zalloc`() with `M_WAITOK` flag set" +msgstr "" +"Llamadas a man:malloc[9] y `uma_zalloc`() con el flag `M_WAITOK` establecido" + +#. type: Plain text +#: documentation/content/en/articles/geom-class/_index.adoc:398 +msgid "sx and other sleepable locks" +msgstr "sx y otros sleepable locks" + +#. type: Plain text +#: documentation/content/en/articles/geom-class/_index.adoc:402 +msgid "" +"This restriction is here to stop GEOM code clogging the I/O request path, " +"since sleeping is usually not time-bound and there can be no guarantees on " +"how long will it take (there are some other, more technical reasons also). " +"It also means that there is not much that can be done in those threads; for " +"example, almost any complex thing requires memory allocation. Fortunately, " +"there is a way out: creating additional kernel threads." +msgstr "" +"Esta restricción está aquí para impedir que el código GEOM obstruya la ruta " +"de las solicitudes de E/S, ya que el dormir no tiene limite de tiempo y " +"puede no haber garantías sobre cuánto tiempo tardará (también hay algunas " +"otras razones más técnicas). También significa que no hay mucho que se pueda " +"hacer en estos hilos; por ejemplo, prácticamente cualquier cosa compleja " +"requiere asignación de memoria. Afortunadamente, hay una salida: crear hilos " +"adicionales en el kernel." + +#. type: Title === +#: documentation/content/en/articles/geom-class/_index.adoc:404 +#, no-wrap +msgid "Kernel Threads for Use in GEOM Code" +msgstr "Hilos del kernel para usar en el código GEOM" + +#. type: Plain text +#: documentation/content/en/articles/geom-class/_index.adoc:407 +msgid "" +"Kernel threads are created with man:kthread_create[9] function, and they are " +"sort of similar to userland threads in behavior, only they cannot return to " +"caller to signify termination, but must call man:kthread_exit[9]." +msgstr "" +"Los hilos del kernel se crean con la función man:kthread_create[9] y se " +"comportan de una forma similar a los hilos en espacio de usuario, sólo que " +"no pueden volver al llamante para indicarles que han terminado sino que " +"tienen que invocar man:kthread_exit[9]." + +#. type: Plain text +#: documentation/content/en/articles/geom-class/_index.adoc:410 +msgid "" +"In GEOM code, the usual use of threads is to offload processing of requests " +"from `g_down` thread (the `.start`() function). These threads look like " +"\"event handlers\": they have a linked list of event associated with them " +"(on which events can be posted by various functions in various threads so it " +"must be protected by a mutex), take the events from the list one by one and " +"process them in a big `switch`() statement." +msgstr "" +"En el código GEOM, el uso habitual de los hilos es para descargar el " +"procesamiento de peticiones del hilo `g_down`(la función `.start`()). Estos " +"hilos parecen \"manejadores de eventos\": tienen vinculada una lista de " +"eventos asociados a ellos (en los cuales los eventos pueden publicarse " +"mediante varias funciones en varios hilos, por lo que deben estar protegidos " +"por un mutex), toma los eventos de la lista, uno por uno, y los procesa en " +"una gran instrucción `switch`()." + +#. type: Plain text +#: documentation/content/en/articles/geom-class/_index.adoc:415 +msgid "" +"The main benefit of using a thread to handle I/O requests is that it can " +"sleep when needed. Now, this sounds good, but should be carefully thought " +"out. Sleeping is well and very convenient but can very effectively destroy " +"performance of the geom transformation. Extremely performance-sensitive " +"classes probably should do all the work in `.start`() function call, taking " +"great care to handle out-of-memory and similar errors." +msgstr "" +"La principal ventaja de utilizar un hilo para manejar las solicitudes de E/S " +"es que pueden dormir (sleep) cuando sea necesario. Ahora, esto suena bien, " +"pero se debe pensar cuidadosamente. Dormir (sleeping) es bueno y muy " +"conveniente, pero puede ser muy efectivo destruyendo el rendimiento de la " +"transformación de geom. Las clases extremadamente sensibles al rendimiento " +"probablemente deberían hacer todo el trabajo en la llamada a la función `." +"start`(), teniendo mucho cuidado de manejar los errores de falta de memoria " +"y similares." + +#. type: Plain text +#: documentation/content/en/articles/geom-class/_index.adoc:419 +msgid "" +"The other benefit of having a event-handler thread like that is to serialize " +"all the requests and responses coming from different geom threads into one " +"thread. This is also very convenient but can be slow. In most cases, " +"handling of `.done`() requests can be left to the `g_up` thread." +msgstr "" +"El otro beneficio de tener un hilo manejador de eventos como este es " +"serializar en un sólo hilo todas las peticiones y respuestas que vienen de " +"los distintos hilos de geom. Esto también es muy cómodo pero puede ser " +"lento. En la mayoría de los casos, el manejo de las peticiones de `.done`() " +"se puede dejar en manos del hilo `g_up`." + +#. type: Plain text +#: documentation/content/en/articles/geom-class/_index.adoc:422 +msgid "" +"Mutexes in FreeBSD kernel (see man:mutex[9]) have one distinction from their " +"more common userland cousins - the code cannot sleep while holding a " +"mutex). If the code needs to sleep a lot, man:sx[9] locks may be more " +"appropriate. On the other hand, if you do almost everything in a single " +"thread, you may get away with no mutexes at all." +msgstr "" +"Los mutex en el kernel de FreeBSD (consulta man:mutex[9]) tienen una " +"característica distintiva respecto de sus primos en espacio de usuario - el " +"código no puede dormir mientras se tiene un mutex cogido. Si el código " +"necesita dormir a menudo, los locks man:sx[9] podrían ser más apropiados. " +"Por otro lado, si haces casi todo en un solo hilo, podrías no necesitar " +"mutex en absoluto." + +#~ msgid "" +#~ "include::shared/attributes/attributes-{{% lang %}}.adoc[] include::shared/" +#~ "{{% lang %}}/teams.adoc[] include::shared/{{% lang %}}/mailing-lists." +#~ "adoc[] include::shared/{{% lang %}}/urls.adoc[]" +#~ msgstr "" +#~ "include::shared/attributes/attributes-{{% lang %}}.adoc[]\n" +#~ "include::shared/{{% lang %}}/teams.adoc[]\n" +#~ "include::shared/{{% lang %}}/mailing-lists.adoc[]\n" +#~ "include::shared/{{% lang %}}/urls.adoc[]"