Index: head/pt_BR.ISO8859-1/articles/geom-class/article.xml =================================================================== --- head/pt_BR.ISO8859-1/articles/geom-class/article.xml (revision 54405) +++ head/pt_BR.ISO8859-1/articles/geom-class/article.xml (revision 54406) @@ -1,474 +1,474 @@
Escrevendo uma classe GEOM Ivan Voras
ivoras@FreeBSD.org
FreeBSD is a registered trademark of the FreeBSD Foundation. Intel, Celeron, Centrino, Core, EtherExpress, i386, i486, Itanium, Pentium, and Xeon are trademarks or registered trademarks of Intel Corporation or its subsidiaries in the United States and other countries. Many of the designations used by manufacturers and sellers to distinguish their products are claimed as trademarks. Where those designations appear in this document, and the FreeBSD Project was aware of the trademark claim, the designations have been followed by the or the ® symbol. $FreeBSD$ $FreeBSD$ Este texto documenta alguns pontos de partida no desenvolvimento de classes GEOM e módulos do kernel em geral. Supõe-se que o leitor esteja familiarizado com a programação C do userland.
Introdução Documentação A documentação sobre programação do kernel é escassa - é uma das poucas áreas na qual não há quase nada de tutoriais amigáveis, e a frase usa a fonte! realmente é verdadeira. No entanto, existem alguns pedaços (alguns deles seriamente desatualizados) flutuando por ai e que devem ser estudados antes de começar a codificar: O Manual do Desenvolvedor do FreeBSD - parte do projeto de documentação, ele não contém nenhum informação específica para a programação do kernel, mas possui algumas informações gerais úteis. O Manual de Arquitetura do FreeBSD - também do projeto de documentação, contém descrições de várias instalações e procedimentos de baixo nível. O capítulo mais importante é o 13, Escrevendo drivers de dispositivo FreeBSD. A seção Blueprints do site do FreeBSD Diary contém vários artigos interessantes sobre os recursos do kernel. As páginas de manual na seção 9 - para documentação importante sobre as funções do kernel. A página man geom4 e os Slides sobre o GEOM de PHK - para uma introdução geral do subsistema GEOM. Páginas de manual g_bio9, g_event9, g_data9, g_geom9, g_provider9 g_consumer9, g_access9 & outros ligados a partir deles, para documentação sobre funcionalidades específicas. - A página do manual style9 - para documentação sobre as convenções de estilo de codificação que devem ser seguidas para qualquer código que se destine a ser incorporado à Árvore do Subversion do FreeBSD. + A página do manual style9 - para documentação sobre as convenções de estilo de codificação que devem ser seguidas para qualquer código que se destine a ser incorporado na árvore do FreeBSD. Preliminares A melhor maneira de fazer o desenvolvimento do kernel é ter (pelo menos) dois computadores separados. Um deles conteria o ambiente de desenvolvimento e o código fonte, e o outro seria usado para testar o código recém escrito, inicializando por meio da rede e montando seu sistema de arquivo a partir do primeiro computador. Desta forma, se o novo código contiver erros e travar a máquina, isso não irá atrapalhar o código fonte (e nem nenhum outros dado vivo). O segundo sistema nem sequer requer um monitor adequado. Em vez disso, ele pode ser conectado por meio de um cabo serial ou KVM ao primeiro computador. Mas, como nem todo mundo tem dois ou mais computadores à mão, há algumas coisas que podem ser feitas para preparar um sistema vivo para desenvolver código para o kernel. Esta configuração também é aplicável para desenvolvimento em uma máquina virtual criada com o VMWare ou com o QEmu (a próxima melhor coisa depois de uma máquina de desenvolvimento dedicada). Modificando um sistema para desenvolvimento Para qualquer programação do kernel, um kernel com a opção ativada é obrigatório. Então, digite estas linhas no seu arquivo de configuração do kernel: options INVARIANT_SUPPORT options INVARIANTS Para ter um maior nível de depuração, você também devrá incluir o suporte ao WITNESS, o qual irá alertá-lo sobre erros relacionados a bloqueios (locking): options WITNESS_SUPPORT options WITNESS Para depurar despejos de memória, é necessário um kernel com símbolos de depuração: makeoptions DEBUG=-g Com a maneira usual de instalar o kernel (make installkernel) o kernel de depuração não será instalado automaticamente. Ele é chamado de kernel.debug e fica localizado em /usr/obj/usr/src/sys/KERNELNAME/. Por conveniência, deve ser copiado para /boot/kernel/. Outra conveniência é habilitar o depurador do kernel para que você possa examinar o panic do kernel quando isso acontece. Para isso, insira as seguintes linhas no seu arquivo de configuração do kernel: options KDB options DDB options KDB_TRACE Para que isso funcione, você pode precisar definir um sysctl (se ele não estiver ativado por padrão): debug.debugger_on_panic=1 Kernel panics acontecerão, portanto, deve-se ter cuidado com o cache do sistema de arquivos. Em particular, ter o softupdates habilitado pode significar que a versão mais recente do arquivo pode ser perdida se um panic ocorrer antes de ser committed para armazenamento. Desativar o softupdates produz um grande impacto na performance e ainda não garante a consistência dos dados. A montagem do sistema de arquivos com a opção sync é necessária para isso. Para um compromisso, os atrasos do cache de softupdates podem ser encurtados. Existem três sysctl's que são úteis para isso (melhor ser configurado em /etc/sysctl.conf): kern.filedelay=5 kern.dirdelay=4 kern.metadelay=3 Os números representam segundos. Para depurar os panics do kernel, os dumps do núcleo do kernel são necessários. Como um kernel panic pode tornar os sistemas de arquivos inutilizáveis, esse despejo de memória é primeiramente gravado em uma partição bruta. Normalmente, esta é a partição de swap. Essa partição deve ser pelo menos tão grande quanto a RAM física na máquina. Na próxima inicialização, o despejo é copiado para um arquivo normal. Isso acontece depois que os sistemas de arquivos são verificados e montados e antes que o swap seja ativado. Isto é controlado com duas variáveis /etc/rc.conf: dumpdev="/dev/ad0s4b" dumpdir="/usr/core A variável dumpdev especifica a partição de swap e dumpdir informa ao sistema onde no sistema de arquivos ele deverá realocar o dump principal na reinicialização. A gravação de core dumps é lenta e leva muito tempo, então se você tiver muita memória (>256M) e muitos panics, pode ser frustrante sentar e esperar enquanto isso é feito (duas vezes - primeiro para gravar para o swap, depois para realocá-lo para o sistema de arquivos). É conveniente limitar a quantidade de RAM que o sistema usará através de uma variável do /boot/loader.conf: hw.physmem="256M" Se os panics são frequentes e os sistemas de arquivos são grandes (ou você simplesmente não confia em softupdates + background fsck), é aconselhável desligar o fsck em background através da variável /etc/rc.conf: background_fsck="NO" Dessa forma, os sistemas de arquivos sempre serão verificados quando necessário. Observe que, com o fsck em segundo plano, um novo panic pode acontecer enquanto ele está verificando os discos. Novamente, a maneira mais segura é não ter muitos sistemas de arquivos locais, usando o outro computador como um servidor NFS. Começando o projeto Para o propósito de criar uma nova classe GEOM, um subdiretório vazio deve ser criado sob um diretório arbitrário acessível pelo usuário. Você não precisa criar o diretório do módulo em /usr/src. O Makefile É uma boa prática criar Makefiles para cada projeto de codificação não trivial, o que obviamente inclui módulos do kernel. Criar o Makefile é simples graças a um extenso conjunto de rotinas auxiliares fornecidas pelo sistema. Em suma, aqui está um exemplo de como um Makefile mínimo para um módulo do kernel se parece: SRCS=g_journal.c KMOD=geom_journal .include <bsd.kmod.mk> Este Makefile (com nomes de arquivos alterados) serve para qualquer módulo do kernel, e uma classe GEOM pode residir em apenas um módulo do kernel. Se mais de um arquivo for necessário, liste-o na variável SRCS, separado com espaço em branco de outros nomes de arquivos. Programação do kernel do FreeBSD Alocação de memória Veja o malloc9. A alocação básica de memória é apenas ligeiramente diferente do seu userland equivalente. Mais notavelmente, malloc() e free() aceitam parâmetros adicionais conforme descrito na página do manual. Um malloc type deve ser declarado na seção de declaração de um arquivo fonte, assim: static MALLOC_DEFINE(M_GJOURNAL, "gjournal data", "GEOM_JOURNAL Data"); Para usar esta macro, os cabeçalhos sys/param.h, sys/kernel.h e sys/malloc.h devem ser incluídos. Existe outro mecanismo para alocar memória, o UMA (Universal Memory Allocator). Veja uma9 para detalhes, mas ele é um tipo especial de alocador usado principalmente para alocação rápida de listas compostas de itens do mesmo tamanho (por exemplo, matrizes dinâmicas de estruturas). Listas e filas Veja queue3. Há MUITOS casos quando uma lista de coisas precisa ser mantida. Felizmente, essa estrutura de dados é implementada (de várias maneiras) por macros C incluídas no sistema. O tipo de lista mais usado é o TAILQ, porque é o mais flexível. É também aquele com os maiores requisitos de memória (seus elementos são duplamente vinculados) e também o mais lento (embora a variação de velocidade seja mais da ordem de várias instruções da CPU, portanto, ela não deve ser levada a sério). Se a velocidade de recuperação de dados for muito importante, veja tree3 e hashinit9. BIOS A estrutura bio é usada para todas e quaisquer operações de Input/Output relativas ao GEOM. Ele basicamente contém informações sobre qual dispositivo ('provedor') deve satisfazer a solicitação, tipo de pedido, offset, comprimento, ponteiro para um buffer e um monte de sinalizadores específicos do usuário e campos que podem ajudar a implementar vários hacks. O importante aqui é que os bios são tratados de forma assíncrona. Isso significa que, na maior parte do código, não há nenhum análogo as chamadas read2 e write2 que não retornam até que uma solicitação seja feita. Em vez disso, uma função fornecida pelo desenvolvedor é chamada como uma notificação quando a solicitação é concluída (ou resulta em erro). O modelo de programação assíncrona (também chamado de orientado a eventos) é um pouco mais difícil do que o imperativo muito mais usado no userland (pelo menos leva um tempo para se acostumar com isso). Em alguns casos, as rotinas auxiliares g_write_data() e g_read_data() podem ser usadas, mas nem sempre. Em particular, elas não podem ser usadas quando um mutex é mantido; por exemplo, o mutex de topologia GEOM ou o mutex interno mantido durante as funções .start() e .stop(). Programação GEOM Ggate Se o desempenho máximo não for necessário, uma maneira muito mais simples de fazer uma transformação de dados é implementá-lo na área do usuário por meio do recurso ggate (GEOM gate). Infelizmente, não existe uma maneira fácil de converter ou até mesmo compartilhar código entre as duas abordagens. Classe GEOM Classes GEOM são transformações nos dados. Essas transformações podem ser combinadas em uma forma de árvore. Instâncias de classes GEOM são chamadas de geoms. Cada classe GEOM possui vários métodos de classe que são chamados quando não há nenhuma instância geom disponível (ou simplesmente não estão vinculados a uma única instância): .init é chamada quando o GEOM toma conhecimento de uma classe GEOM (quando o módulo do kernel é carregado). .fini é chamada quando o GEOM abandona a classe (quando o módulo é descarregado) .taste é chamada next, uma vez para cada provedor que o sistema tiver disponível. Se aplicável, essa função geralmente criará e iniciará uma instância geom. .destroy_geom é chamada quando o geom deve ser desfeito .ctlconf é chamado quando o usuário solicita a reconfiguração do geom existente Também são definidas as funções de evento GEOM, que serão copiadas para a instância geom. O campo .geom na estrutura g_class é uma LISTA de geoms instanciados a partir da classe. Estas funções são chamadas a partir da thread g_event do kernel. Softc O nome softc é um termo legado para dados privados do driver. O nome provavelmente vem do termo arcaico bloco de controle de software. No GEOM, ele é uma estrutura (mais precisamente: ponteiro para uma estrutura) que pode ser anexada a uma instância geom para armazenar quaisquer dados que sejam privados para a instância geom. A maioria das classes GEOM possui os seguintes membros: struct g_provider *provider : O provedor que este geom instância uint16_t n_disks : Número de consumidores que este geom consome struct g_consumer **disks: Array de struct g_consumer*. (Não é possível usar apenas uma única via indireta porque o struct g_consumer* é criado em nosso nome pela GEOM). A estrutura softc contém todo o estado da instância geom. Cada instância geom possui seu próprio softc. Metadados O formato dos metadados é mais ou menos dependente da classe, mas DEVE começar com: Buffer de 16 bytes para uma assinatura de terminação nula (geralmente o nome da classe) ID da versão uint32 Assume-se que as classes geom sabem como lidar com metadados com ID de versão menores que os deles. Os metadados estão localizados no último setor do provedor (e, portanto, devem caber nele). (Tudo isso depende da implementação, mas todo o código existente funciona assim, e é suportado por bibliotecas.) Rotulando/criando um GEOM A sequência de eventos é: o usuário chama o utilitário geom8 (ou um de seus equivalentes hardlinked) o utilitário descobre qual classe geom ele é suposto manipular e procura pela biblioteca geom_CLASSNAME.so (geralmente em /lib/geom). ele dlopen3-s a biblioteca, extrai as definições dos parâmetros da linha de comandos e funções auxiliares. No caso da criação/rotulação de um novo geom, isso é o que acontece: O geom8 procura no argumento da linha de comando pelo comando (geralmente ) e chama uma função auxiliar . A função auxiliar verifica parâmetros e reúne metadados, que são gravados em todos os provedores envolvidos. Este estraga geoms existentes (se existirem) e inicializa uma nova rodada de degustação dos provedores. A classe geom pretendida reconhece os metadados e carrega o geom. (A sequência de eventos acima é dependente da implementação, mas todo o código existente funciona assim, e é suportado pelas bibliotecas.) Estrutura do Comando GEOM A biblioteca helper geom_CLASSNAME.so exporta a estrutura class_commands, que é uma matriz dos elementos struct g_command. Os comandos são uniformes no formato e se parecem com: verb [-options] geomname [other] Verbos comuns são: label - para gravar metadados em dispositivos para que eles possam ser reconhecidos em degustações e criados em geoms destroy - para destruir metadados, para que as geoms sejam destruídas Opções comuns são: -v : be verbose -f : force Muitas ações, como rotular e destruir metadados, podem ser executadas no userland. Para isso, struct g_command fornece o campo gc_func que pode ser definido para uma função (no mesmo .so) que será chamada para processar um verbo. Se gc_func for NULL, o comando será passado para o módulo do kernel, para a função .ctlreq da classe geom. Geoms Geoms são instâncias de classes GEOM. Eles possuem dados internos (uma estrutura softc) e algumas funções com as quais eles respondem a eventos externos. As funções de evento são: .acess: calcula permissões (leitura / escrita / exclusiva) .dumpconf: retorna informações formatadas em XML sobre o geom .orphan: chamado quando algum provedor subjacente é desconectado .spoiled: chamado quando algum provedor subjacente é gravado .start: lida com I/O Estas funções são chamadas a partir da thread g_down do kernel e não pode haver sleeping neste contexto, (veja a definição de sleeping em outro lugar) o que limita um pouco o que pode ser feito, mas força o manuseio a ser rápido . Destes, a função mais importante para fazer o trabalho útil real é a função .start(), que é chamada quando uma requisição BIO chega para um provedor gerenciado por uma instância da classe geom. Threads GEOM Existem três threads de kernel criados e executados pelo framework GEOM: g_down : trata de solicitações provenientes de entidades de alto nível (como uma solicitação do userland) no caminho para dispositivos físicos g_up : lida com respostas de drivers de dispositivos para solicitações feitas por entidades de nível superior g_event : lida com todos os outros casos: criação de instâncias geom, contagem de acessos, eventos spoil, etc. Quando um processo do usuário emite um pedido de leitura de dados X no deslocamento Y de um arquivo, isto é o que acontece: O sistema de arquivos converte o pedido em uma instância struct bio e o transmite para o subsistema GEOM. Ele sabe o que a instância geom deve manipular porque os sistemas de arquivos são hospedados diretamente em uma instância geom. A requisição termina como uma chamada para a função .start() feita para a thread g_down e atinge a instância geom de nível superior. Essa instância geom de nível superior (por exemplo, o segmentador de partições) determina que a solicitação deve ser roteada para uma instância de nível inferior (por exemplo, o driver de disco). Ele faz uma cópia da solicitação bio (solicitações bio SEMPRE precisam ser copiadas entre instâncias, com g_clone_bio()!), modifica os campos de dados offset e de provedor de destino e executa a cópia com g_io_request() O driver de disco obtém a solicitação bio também como uma chamada para .start() na thread g_down. Ela fala com o hardware, recupera os dados e chama g_io_deliver() na bio. Agora, a notificação de bio conclusão borbulha na thread g_up. Primeiro, o slicer de partição obtém .done() chamado na thread g_up, ele usa as informações armazenadas na bio para liberar a estrutura bio clonada (com g_destroy_bio()) e chama g_io_deliver() no pedido original. O sistema de arquivos obtém os dados e os transfere para o usuário. Veja a página de manual para o g_bio9 para obter informações sobre como os dados são passados para frente e para trás na estrutura bio (observe em particular os campos bio_parent e bio_children e como eles são manipulados). Uma característica importante: NAS THREADS G_UP E G_DOWN NÃO SE PODE DORMIR (SELEEPING). Isso significa que nenhuma das seguintes coisas pode ser feita nessas threads (a lista não é completa, mas apenas informativa): Chamadas para msleep() e tsleep(), obviamente. Chamadas para g_write_data() e g_read_data(), porque estes dormem entre passar os dados para os consumidores e retornar. Esperando I/O. Chamadas para malloc9 e uma_zalloc() com o conjunto de flags M_WAITOK sx e outros sleepable locks Esta restrição está aqui para impedir que o código GEOM obstrua o caminho da solicitação de I/O, já que sleeping normalmente não é limitado pelo tempo e não pode haver garantias sobre quanto tempo levará (também existem algumas outras razões mais técnicas). Isso também significa que não existe muito o que possa ser feito nessas threads; por exemplo, quase qualquer coisa complexa requer alocação de memória. Felizmente, existe uma saída: criar threads adicionais no kernel. Threads de kernel para uso no código GEOM As threads do kernel são criadas com a função kthread_create9, e elas são semelhantes aos threads do userland no comportamento, eles somente não podem retornar ao chamador para exprimir a conclusão, mas deve chamar kthread_exit9. No código GEOM, o uso usual de threads é para descarregar o processamento de requisições da thread g_down (a função .start). Estas threads se parecem com um event handlers: elas têm uma lista encadeada de eventos associados a elas (nos quais eventos podem ser postados por várias funções em várias threads, portanto, devem ser protegidos por um mutex), pegam os eventos da lista, um por um, e processa-os em uma grande instrução switch(). A principal vantagem de usar uma thread para lidar com solicitações de I/O é que ela pode dormir quando necessário. Agora, isso parece bom, mas deve ser cuidadosamente pensado. Dormir é bom e muito conveniente, mas pode ser muito efetivo em destruir o desempenho da transformação geom. As classes extremamente sensíveis ao desempenho provavelmente devem fazer todo o trabalho na chamada de função .start(), tomando muito cuidado para lidar com erros de falta de memória e similares. O outro benefício de ter uma thread de manipulação de eventos como essa é serializar todas as solicitações e respostas provenientes de diferentes threads geom em uma thread. Isso também é muito conveniente, mas pode ser lento. Na maioria dos casos, o tratamento de pedidos .done() pode ser deixado para a thread g_up. Mutexes no kernel do FreeBSD (veja mutex9) têm uma distinção de seus primos mais comuns do userland - o código não pode dormir enquanto estiver segurando um mutex). Se o código precisar dormir muito, os bloqueios sx9 podem ser mais apropriados. Por outro lado, se você faz quase tudo em um único thread, você pode se safar sem utilizar mutexes.
Index: head/pt_BR.ISO8859-1/articles/geom-class/pt_BR.po =================================================================== --- head/pt_BR.ISO8859-1/articles/geom-class/pt_BR.po (revision 54405) +++ head/pt_BR.ISO8859-1/articles/geom-class/pt_BR.po (revision 54406) @@ -1,1542 +1,1544 @@ # $FreeBSD$ -# Danilo G. Baio , 2018. #zanata -# Edson Brandi , 2018. #zanata +# Danilo G. Baio , 2019. #zanata, 2020. +# Edson Brandi , 2019. #zanata msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" -"POT-Creation-Date: 2018-09-16 19:44+0000\n" -"PO-Revision-Date: 2018-09-16 07:26+0000\n" -"Last-Translator: Copied by Zanata \n" -"Language-Team: \n" +"POT-Creation-Date: 2020-07-26 12:09-0300\n" +"PO-Revision-Date: 2020-07-26 13:16+0000\n" +"Last-Translator: Danilo G. Baio \n" +"Language-Team: Portuguese (Brazil) \n" "Language: pt_BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Generator: Zanata 4.6.2\n" -"Plural-Forms: nplurals=2; plural=(n != 1)\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Weblate 4.1.1\n" #. Put one translator per line, in the form NAME , YEAR1, YEAR2 msgctxt "_" msgid "translator-credits" msgstr "" "Edson Brandi, ebrandi@FreeBSD.org, 2018\n" "Danilo G. Baio, dbaio@FreeBSD.org, 2018" #. (itstool) path: info/title #: article.translate.xml:5 msgid "Writing a GEOM Class" msgstr "Escrevendo uma classe GEOM" #. (itstool) path: affiliation/address #: article.translate.xml:14 #, no-wrap msgid "" "\n" "\t ivoras@FreeBSD.org\n" "\t " msgstr "" "\n" "\t ivoras@FreeBSD.org\n" "\t " #. (itstool) path: authorgroup/author #: article.translate.xml:8 msgid "" " Ivan Voras <_:address-1/> " msgstr "" " Ivan Voras <_:address-1/> " #. (itstool) path: legalnotice/para #: article.translate.xml:22 msgid "FreeBSD is a registered trademark of the FreeBSD Foundation." msgstr "FreeBSD is a registered trademark of the FreeBSD Foundation." #. (itstool) path: legalnotice/para #: article.translate.xml:24 msgid "" "Intel, Celeron, Centrino, Core, EtherExpress, i386, i486, Itanium, Pentium, " "and Xeon are trademarks or registered trademarks of Intel Corporation or its " "subsidiaries in the United States and other countries." msgstr "" "Intel, Celeron, Centrino, Core, EtherExpress, i386, i486, Itanium, Pentium, " "and Xeon are trademarks or registered trademarks of Intel Corporation or its " "subsidiaries in the United States and other countries." #. (itstool) path: legalnotice/para #: article.translate.xml:28 msgid "" "Many of the designations used by manufacturers and sellers to distinguish " "their products are claimed as trademarks. Where those designations appear in " "this document, and the FreeBSD Project was aware of the trademark claim, the " "designations have been followed by the or the ® symbol." msgstr "" "Many of the designations used by manufacturers and sellers to distinguish " "their products are claimed as trademarks. Where those designations appear in " "this document, and the FreeBSD Project was aware of the trademark claim, the " "designations have been followed by the or the ® symbol." #. (itstool) path: info/pubdate #. (itstool) path: info/releaseinfo #: article.translate.xml:36 article.translate.xml:38 msgid "" -"$FreeBSD: head/en_US.ISO8859-1/articles/geom-class/article.xml 48489 " -"2016-03-28 17:30:19Z jgh $" -msgstr "$FreeBSD$" +"$FreeBSD: head/en_US.ISO8859-1/articles/geom-class/article.xml 54291 " +"2020-06-23 13:48:26Z emaste $" +msgstr "" +"$FreeBSD: head/en_US.ISO8859-1/articles/geom-class/article.xml 54291 " +"2020-06-23 13:48:26Z emaste $" #. (itstool) path: abstract/para #: article.translate.xml:41 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 alguns pontos de partida no desenvolvimento de classes " "GEOM e módulos do kernel em geral. Supõe-se que o leitor esteja " "familiarizado com a programação C do userland." #. (itstool) path: sect1/title #: article.translate.xml:50 msgid "Introduction" msgstr "Introdução" #. (itstool) path: sect2/title #: article.translate.xml:53 msgid "Documentation" msgstr "Documentação" #. (itstool) path: sect2/para #: article.translate.xml:55 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 "" "A documentação sobre programação do kernel é escassa - é uma das poucas " "áreas na qual não há quase nada de tutoriais amigáveis, e a frase usa " "a fonte! realmente é verdadeira. No entanto, existem alguns pedaços " "(alguns deles seriamente desatualizados) flutuando por ai e que devem ser " "estudados antes de começar a codificar:" #. (itstool) path: listitem/para #: article.translate.xml:64 msgid "" "The 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 "" "O Manual do Desenvolvedor do FreeBSD - parte do " "projeto de documentação, ele não contém nenhum informação específica para a " "programação do kernel, mas possui algumas informações gerais úteis." #. (itstool) path: listitem/para #: article.translate.xml:72 msgid "" "The FreeBSD Architecture Handbook — also from the " "documentation project, contains descriptions of several low-level facilities " "and procedures. The most important chapter is 13, Writing FreeBSD device drivers." msgstr "" "O Manual de Arquitetura do FreeBSD - também do " "projeto de documentação, contém descrições de várias instalações e " "procedimentos de baixo nível. O capítulo mais importante é o 13, Escrevendo drivers de dispositivo FreeBSD." #. (itstool) path: listitem/para #: article.translate.xml:81 msgid "" "The Blueprints section of FreeBSD Diary web site — contains several interesting articles on " "kernel facilities." msgstr "" "A seção Blueprints do site do FreeBSD Diary contém vários artigos interessantes sobre os " "recursos do kernel." #. (itstool) path: listitem/para #: article.translate.xml:88 msgid "" "The man pages in section 9 — for important documentation on kernel functions." msgstr "" "As páginas de manual na seção 9 - para documentação importante sobre as " "funções do kernel." #. (itstool) path: listitem/para #: article.translate.xml:93 msgid "" "The geom4 man page and PHK's GEOM slides — for general introduction of the GEOM " "subsystem." msgstr "" "A página man geom4 e os Slides sobre o GEOM de PHK - para uma introdução geral do " "subsistema GEOM." #. (itstool) path: listitem/para #: article.translate.xml:99 msgid "" "Man pages g_bio9, g_event9, " "g_data9, g_geom9, " "g_provider9 g_consumer9, " "g_access9 & others linked from those, for documentation " "on specific functionalities." msgstr "" "Páginas de manual g_bio9, " "g_event9, g_data9, " "g_geom9, g_provider9 " "g_consumer9, g_access9 & outros ligados a " "partir deles, para documentação sobre funcionalidades específicas." #. (itstool) path: listitem/para #: article.translate.xml:107 msgid "" "The style9 man page — for documentation on the coding-style " "conventions which must be followed for any code which is to be committed to " -"the FreeBSD Subversion tree." +"the FreeBSD tree." msgstr "" "A página do manual style9 - para documentação " "sobre as convenções de estilo de codificação que devem ser seguidas para " -"qualquer código que se destine a ser incorporado à Árvore do Subversion do " -"FreeBSD." +"qualquer código que se destine a ser incorporado na árvore do FreeBSD." #. (itstool) path: sect1/title #: article.translate.xml:117 msgid "Preliminaries" msgstr "Preliminares" #. (itstool) path: sect1/para #: article.translate.xml:119 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 "" "A melhor maneira de fazer o desenvolvimento do kernel é ter (pelo menos) " "dois computadores separados. Um deles conteria o ambiente de desenvolvimento " "e o código fonte, e o outro seria usado para testar o código recém escrito, " "inicializando por meio da rede e montando seu sistema de arquivo a partir do " "primeiro computador. Desta forma, se o novo código contiver erros e travar a " "máquina, isso não irá atrapalhar o código fonte (e nem nenhum outros dado " "vivo). O segundo sistema nem sequer requer um monitor " "adequado. Em vez disso, ele pode ser conectado por meio de um cabo serial ou " "KVM ao primeiro computador." #. (itstool) path: sect1/para #: article.translate.xml:130 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 VMWare or QEmu virtual machine (the next best " "thing after a dedicated development machine)." msgstr "" "Mas, como nem todo mundo tem dois ou mais computadores à mão, há algumas " "coisas que podem ser feitas para preparar um sistema vivo " "para desenvolver código para o kernel. Esta configuração também é aplicável " "para desenvolvimento em uma máquina virtual criada com o VMWare ou com o QEmu (a próxima melhor coisa depois de uma máquina de " "desenvolvimento dedicada)." #. (itstool) path: sect2/title #: article.translate.xml:138 msgid "Modifying a System for Development" msgstr "Modificando um sistema para desenvolvimento" #. (itstool) path: sect2/para #: article.translate.xml:140 msgid "" "For any kernel programming a kernel with enabled " "is a must-have. So enter these in your kernel configuration file:" msgstr "" "Para qualquer programação do kernel, um kernel com a opção " " ativada é obrigatório. Então, digite estas " "linhas no seu arquivo de configuração do kernel:" #. (itstool) path: sect2/programlisting #: article.translate.xml:144 #, no-wrap msgid "" "options INVARIANT_SUPPORT\n" "options INVARIANTS" msgstr "" "options INVARIANT_SUPPORT\n" "options INVARIANTS" #. (itstool) path: sect2/para #: article.translate.xml:147 msgid "" "For more debugging you should also include WITNESS support, which will alert " "you of mistakes in locking:" msgstr "" "Para ter um maior nível de depuração, você também devrá incluir o suporte ao " "WITNESS, o qual irá alertá-lo sobre erros relacionados a bloqueios (locking):" #. (itstool) path: sect2/programlisting #: article.translate.xml:150 #, no-wrap msgid "" "options WITNESS_SUPPORT\n" "options WITNESS" msgstr "" "options WITNESS_SUPPORT\n" "options WITNESS" #. (itstool) path: sect2/para #: article.translate.xml:153 msgid "For debugging crash dumps, a kernel with debug symbols is needed:" msgstr "" "Para depurar despejos de memória, é necessário um kernel com símbolos de " "depuração:" #. (itstool) path: sect2/programlisting #: article.translate.xml:156 #, no-wrap msgid " makeoptions DEBUG=-g" msgstr " makeoptions DEBUG=-g" #. (itstool) path: sect2/para #: article.translate.xml:158 msgid "" "With the usual way of installing the kernel (make installkernel) the debug kernel will not be automatically installed. It is called " "kernel.debug and located in /usr/obj/usr/src/" "sys/KERNELNAME/. For convenience it should be copied to " "/boot/kernel/." msgstr "" "Com a maneira usual de instalar o kernel (make installkernel) o kernel de depuração não será instalado automaticamente. Ele é " "chamado de kernel.debug e fica localizado em " "/usr/obj/usr/src/sys/KERNELNAME/. Por conveniência, " "deve ser copiado para /boot/kernel/." #. (itstool) path: sect2/para #: article.translate.xml:166 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 "" "Outra conveniência é habilitar o depurador do kernel para que você possa " "examinar o panic do kernel quando isso acontece. Para isso, insira as " "seguintes linhas no seu arquivo de configuração do kernel:" #. (itstool) path: sect2/programlisting #: article.translate.xml:170 #, no-wrap msgid "" "options KDB\n" "options DDB\n" "options KDB_TRACE" msgstr "" "options KDB\n" "options DDB\n" "options KDB_TRACE" #. (itstool) path: sect2/para #: article.translate.xml:174 msgid "" "For this to work you might need to set a sysctl (if it is not on by default):" msgstr "" "Para que isso funcione, você pode precisar definir um sysctl (se ele não " "estiver ativado por padrão):" #. (itstool) path: sect2/programlisting #: article.translate.xml:177 #, no-wrap msgid " debug.debugger_on_panic=1" msgstr " debug.debugger_on_panic=1" #. (itstool) path: sect2/para #: article.translate.xml:179 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 /etc/sysctl.conf):" msgstr "" "Kernel panics acontecerão, portanto, deve-se ter cuidado com o cache do " "sistema de arquivos. Em particular, ter o softupdates habilitado pode " "significar que a versão mais recente do arquivo pode ser perdida se um panic " "ocorrer antes de ser committed para armazenamento. Desativar o softupdates " "produz um grande impacto na performance e ainda não garante a consistência " "dos dados. A montagem do sistema de arquivos com a opção sync " "é necessária para isso. Para um compromisso, os atrasos do cache de " "softupdates podem ser encurtados. Existem três sysctl's que são úteis para " "isso (melhor ser configurado em /etc/sysctl.conf):" #. (itstool) path: sect2/programlisting #: article.translate.xml:190 #, no-wrap msgid "" "kern.filedelay=5\n" "kern.dirdelay=4\n" "kern.metadelay=3" msgstr "" "kern.filedelay=5\n" "kern.dirdelay=4\n" "kern.metadelay=3" #. (itstool) path: sect2/para #: article.translate.xml:194 msgid "The numbers represent seconds." msgstr "Os números representam segundos." #. (itstool) path: sect2/para #: article.translate.xml:196 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 " "/etc/rc.conf variables:" msgstr "" "Para depurar os panics do kernel, os dumps do núcleo do kernel são " "necessários. Como um kernel panic pode tornar os sistemas de arquivos " "inutilizáveis, esse despejo de memória é primeiramente gravado em uma " "partição bruta. Normalmente, esta é a partição de swap. Essa partição deve " "ser pelo menos tão grande quanto a RAM física na máquina. Na próxima " "inicialização, o despejo é copiado para um arquivo normal. Isso acontece " "depois que os sistemas de arquivos são verificados e montados e antes que o " "swap seja ativado. Isto é controlado com duas variáveis /etc/rc." "conf:" #. (itstool) path: sect2/programlisting #: article.translate.xml:206 #, no-wrap msgid "" "dumpdev=\"/dev/ad0s4b\"\n" "dumpdir=\"/usr/core " msgstr "" "dumpdev=\"/dev/ad0s4b\"\n" "dumpdir=\"/usr/core " #. (itstool) path: sect2/para #: article.translate.xml:209 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 "" "A variável dumpdev especifica a partição de swap e " "dumpdir informa ao sistema onde no sistema de arquivos " "ele deverá realocar o dump principal na reinicialização." #. (itstool) path: sect2/para #: article.translate.xml:214 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 /boot/loader.conf tunable:" msgstr "" "A gravação de core dumps é lenta e leva muito tempo, então se você tiver " "muita memória (>256M) e muitos panics, pode ser frustrante sentar e " "esperar enquanto isso é feito (duas vezes - primeiro para gravar para o " "swap, depois para realocá-lo para o sistema de arquivos). É conveniente " "limitar a quantidade de RAM que o sistema usará através de uma variável do " "/boot/loader.conf:" #. (itstool) path: sect2/programlisting #: article.translate.xml:222 #, no-wrap msgid " hw.physmem=\"256M\"" msgstr " hw.physmem=\"256M\"" #. (itstool) path: sect2/para #: article.translate.xml:224 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 " "/etc/rc.conf variable:" msgstr "" "Se os panics são frequentes e os sistemas de arquivos são grandes (ou você " "simplesmente não confia em softupdates + background fsck), é aconselhável " "desligar o fsck em background através da variável /etc/rc.conf:" #. (itstool) path: sect2/programlisting #: article.translate.xml:229 #, no-wrap msgid " background_fsck=\"NO\"" msgstr " background_fsck=\"NO\"" #. (itstool) path: sect2/para #: article.translate.xml:231 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 "" "Dessa forma, os sistemas de arquivos sempre serão verificados quando " "necessário. Observe que, com o fsck em segundo plano, um novo panic pode " "acontecer enquanto ele está verificando os discos. Novamente, a maneira mais " "segura é não ter muitos sistemas de arquivos locais, usando o outro " "computador como um servidor NFS." #. (itstool) path: sect2/title #: article.translate.xml:239 msgid "Starting the Project" msgstr "Começando o projeto" #. (itstool) path: sect2/para #: article.translate.xml:241 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 /usr/src." msgstr "" "Para o propósito de criar uma nova classe GEOM, um subdiretório vazio deve " "ser criado sob um diretório arbitrário acessível pelo usuário. Você não " "precisa criar o diretório do módulo em /usr/src." #. (itstool) path: sect2/title #: article.translate.xml:248 msgid "The Makefile" msgstr "O Makefile" #. (itstool) path: sect2/para #: article.translate.xml:250 msgid "" "It is good practice to create Makefiles for every " "nontrivial coding project, which of course includes kernel modules." msgstr "" "É uma boa prática criar Makefiles para cada projeto de " "codificação não trivial, o que obviamente inclui módulos do kernel." #. (itstool) path: sect2/para #: article.translate.xml:254 msgid "" "Creating the Makefile is simple thanks to an extensive " "set of helper routines provided by the system. In short, here is how a " "minimal Makefile looks for a kernel module:" msgstr "" "Criar o Makefile é simples graças a um extenso conjunto " "de rotinas auxiliares fornecidas pelo sistema. Em suma, aqui está um exemplo " "de como um Makefile mínimo para um módulo do kernel se " "parece:" #. (itstool) path: sect2/programlisting #: article.translate.xml:260 #, no-wrap msgid "" "SRCS=g_journal.c\n" "KMOD=geom_journal\n" "\n" ".include <bsd.kmod.mk>" msgstr "" "SRCS=g_journal.c\n" "KMOD=geom_journal\n" "\n" ".include <bsd.kmod.mk>" #. (itstool) path: sect2/para #: article.translate.xml:265 msgid "" "This 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 Makefile (com nomes de arquivos alterados) serve " "para qualquer módulo do kernel, e uma classe GEOM pode residir em apenas um " "módulo do kernel. Se mais de um arquivo for necessário, liste-o na variável " "SRCS, separado com espaço em branco de outros nomes de " "arquivos." #. (itstool) path: sect1/title #: article.translate.xml:274 msgid "On FreeBSD Kernel Programming" msgstr "Programação do kernel do FreeBSD" #. (itstool) path: sect2/title #: article.translate.xml:277 msgid "Memory Allocation" msgstr "Alocação de memória" #. (itstool) path: sect2/para #: article.translate.xml:279 msgid "" "See malloc9. 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 "" "Veja o malloc9. A alocação básica de memória é apenas " "ligeiramente diferente do seu userland equivalente. Mais notavelmente, " "malloc() e free() aceitam " "parâmetros adicionais conforme descrito na página do manual." #. (itstool) path: sect2/para #: article.translate.xml:285 msgid "" "A malloc type must be declared in the declaration section of " "a source file, like this:" msgstr "" "Um malloc type deve ser declarado na seção de declaração de " "um arquivo fonte, assim:" #. (itstool) path: sect2/programlisting #: article.translate.xml:288 #, no-wrap msgid " static MALLOC_DEFINE(M_GJOURNAL, \"gjournal data\", \"GEOM_JOURNAL Data\");" msgstr " static MALLOC_DEFINE(M_GJOURNAL, \"gjournal data\", \"GEOM_JOURNAL Data\");" #. (itstool) path: sect2/para #: article.translate.xml:290 msgid "" "To use this macro, sys/param.h, sys/kernel.h and sys/malloc.h headers must be included." msgstr "" "Para usar esta macro, os cabeçalhos sys/param.h, " "sys/kernel.h e sys/malloc.h devem " "ser incluídos." #. (itstool) path: sect2/para #: article.translate.xml:295 msgid "" "There is another mechanism for allocating memory, the UMA (Universal Memory " "Allocator). See uma9 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 "" "Existe outro mecanismo para alocar memória, o UMA (Universal Memory " "Allocator). Veja uma9 para detalhes, mas ele " "é um tipo especial de alocador usado principalmente para alocação rápida de " "listas compostas de itens do mesmo tamanho (por exemplo, matrizes dinâmicas " "de estruturas)." #. (itstool) path: sect2/title #: article.translate.xml:303 msgid "Lists and Queues" msgstr "Listas e filas" #. (itstool) path: sect2/para #: article.translate.xml:305 msgid "" "See queue3. 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 "" "Veja queue3. Há MUITOS casos quando uma lista de coisas " "precisa ser mantida. Felizmente, essa estrutura de dados é implementada (de " "várias maneiras) por macros C incluídas no sistema. O tipo de lista mais " "usado é o TAILQ, porque é o mais flexível. É também aquele com os maiores " "requisitos de memória (seus elementos são duplamente vinculados) e também o " "mais lento (embora a variação de velocidade seja mais da ordem de várias " "instruções da CPU, portanto, ela não deve ser levada a sério)." #. (itstool) path: sect2/para #: article.translate.xml:315 msgid "" "If data retrieval speed is very important, see " "tree3 and hashinit9." msgstr "" "Se a velocidade de recuperação de dados for muito importante, veja " "tree3 e hashinit9." #. (itstool) path: sect2/title #: article.translate.xml:320 msgid "BIOs" msgstr "BIOS" #. (itstool) path: sect2/para #: article.translate.xml:322 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 "" "A estrutura bio é usada para todas e " "quaisquer operações de Input/Output relativas ao GEOM. Ele basicamente " "contém informações sobre qual dispositivo ('provedor') deve satisfazer a " "solicitação, tipo de pedido, offset, comprimento, ponteiro para um buffer e " "um monte de sinalizadores específicos do usuário e campos que " "podem ajudar a implementar vários hacks." #. (itstool) path: sect2/para #: article.translate.xml:330 msgid "" "The important thing here is that bios are handled asynchronously. That means that, in most parts of the " "code, there is no analogue to userland's read2 and " "write2 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 "" "O importante aqui é que os bios são " "tratados de forma assíncrona. Isso significa que, na maior parte do código, " "não há nenhum análogo as chamadas read2 e " "write2 que não retornam até que uma solicitação seja feita. Em vez " "disso, uma função fornecida pelo desenvolvedor é chamada como uma " "notificação quando a solicitação é concluída (ou resulta em erro)." #. (itstool) path: sect2/para #: article.translate.xml:338 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 "" "O modelo de programação assíncrona (também chamado de orientado a " "eventos) é um pouco mais difícil do que o imperativo muito mais " "usado no userland (pelo menos leva um tempo para se acostumar com isso). Em " "alguns casos, as rotinas auxiliares g_write_data() e " "g_read_data() podem ser usadas, mas nem " "sempre. Em particular, elas não podem ser usadas quando um mutex " "é mantido; por exemplo, o mutex de topologia GEOM ou o mutex interno mantido " "durante as funções .start() e .stop()." #. (itstool) path: sect1/title #: article.translate.xml:353 msgid "On GEOM Programming" msgstr "Programação GEOM" #. (itstool) path: sect2/title #: article.translate.xml:356 msgid "Ggate" msgstr "Ggate" #. (itstool) path: sect2/para #: article.translate.xml:358 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 "" "Se o desempenho máximo não for necessário, uma maneira muito mais simples de " "fazer uma transformação de dados é implementá-lo na área do usuário por meio " "do recurso ggate (GEOM gate). Infelizmente, não existe uma maneira fácil de " "converter ou até mesmo compartilhar código entre as duas abordagens." #. (itstool) path: sect2/title #: article.translate.xml:366 msgid "GEOM Class" msgstr "Classe GEOM" #. (itstool) path: sect2/para #: article.translate.xml:368 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 "" "Classes GEOM são transformações nos dados. Essas transformações podem ser " "combinadas em uma forma de árvore. Instâncias de classes GEOM são chamadas " "de geoms." #. (itstool) path: sect2/para #: article.translate.xml:373 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 classe GEOM possui vários métodos de classe que são " "chamados quando não há nenhuma instância geom disponível (ou simplesmente " "não estão vinculados a uma única instância):" #. (itstool) path: listitem/para #: article.translate.xml:379 msgid "" ".init is called when GEOM becomes aware of a GEOM class " "(when the kernel module gets loaded.)" msgstr "" ".init é chamada quando o GEOM toma conhecimento de uma " "classe GEOM (quando o módulo do kernel é carregado)." #. (itstool) path: listitem/para #: article.translate.xml:385 msgid "" ".fini gets called when GEOM abandons the class (when " "the module gets unloaded)" msgstr "" ".fini é chamada quando o GEOM abandona a classe (quando " "o módulo é descarregado)" #. (itstool) path: listitem/para #: article.translate.xml:391 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 "" ".taste é chamada next, uma vez para cada provedor que o " "sistema tiver disponível. Se aplicável, essa função geralmente criará e " "iniciará uma instância geom." #. (itstool) path: listitem/para #: article.translate.xml:398 msgid "" ".destroy_geom is called when the geom should be " "disbanded" msgstr "" ".destroy_geom é chamada quando o geom deve ser desfeito" #. (itstool) path: listitem/para #: article.translate.xml:403 msgid "" ".ctlconf is called when user requests reconfiguration " "of existing geom" msgstr "" ".ctlconf é chamado quando o usuário solicita a " "reconfiguração do geom existente" #. (itstool) path: sect2/para #: article.translate.xml:409 msgid "" "Also defined are the GEOM event functions, which will get copied to the geom " "instance." msgstr "" "Também são definidas as funções de evento GEOM, que serão copiadas para a " "instância geom." #. (itstool) path: sect2/para #: article.translate.xml:412 msgid "" "Field .geom in the g_class structure is a LIST of geoms instantiated from the " "class." msgstr "" "O campo .geom na estrutura g_class é uma LISTA de geoms instanciados a partir da classe." #. (itstool) path: sect2/para #: article.translate.xml:415 msgid "These functions are called from the g_event kernel thread." msgstr "Estas funções são chamadas a partir da thread g_event do kernel." #. (itstool) path: sect2/title #: article.translate.xml:420 msgid "Softc" msgstr "Softc" #. (itstool) path: sect2/para #: article.translate.xml:422 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 "" "O nome softc é um termo legado para dados privados do " "driver. O nome provavelmente vem do termo arcaico bloco de " "controle de software. No GEOM, ele é uma estrutura (mais " "precisamente: ponteiro para uma estrutura) que pode ser anexada a uma " "instância geom para armazenar quaisquer dados que sejam privados para a " "instância geom. A maioria das classes GEOM possui os seguintes membros:" #. (itstool) path: listitem/para #: article.translate.xml:433 msgid "" "struct g_provider *provider : The provider " "this geom instantiates" msgstr "" "struct g_provider *provider : O provedor " "que este geom instância" #. (itstool) path: listitem/para #: article.translate.xml:439 msgid "" "uint16_t n_disks : Number of consumer this geom consumes" msgstr "" "uint16_t n_disks : Número de consumidores que este geom " "consome" #. (itstool) path: listitem/para #: article.translate.xml:444 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*. (Não é possível usar apenas uma única via indireta " "porque o struct g_consumer* é criado em nosso nome pela GEOM)." #. (itstool) path: sect2/para #: article.translate.xml:452 msgid "" "The softc structure contains all the " "state of geom instance. Every geom instance has its own softc." msgstr "" "A estrutura softc contém todo o " "estado da instância geom. Cada instância geom possui seu próprio softc." #. (itstool) path: sect2/title #: article.translate.xml:458 msgid "Metadata" msgstr "Metadados" #. (itstool) path: sect2/para #: article.translate.xml:460 msgid "" "Format of metadata is more-or-less class-dependent, but MUST start with:" msgstr "" "O formato dos metadados é mais ou menos dependente da classe, mas DEVE " "começar com:" #. (itstool) path: listitem/para #: article.translate.xml:465 msgid "16 byte buffer for null-terminated signature (usually the class name)" msgstr "" "Buffer de 16 bytes para uma assinatura de terminação nula (geralmente o nome " "da classe)" #. (itstool) path: listitem/para #: article.translate.xml:470 msgid "uint32 version ID" msgstr "ID da versão uint32" #. (itstool) path: sect2/para #: article.translate.xml:474 msgid "" "It is assumed that geom classes know how to handle metadata with version " "ID's lower than theirs." msgstr "" "Assume-se que as classes geom sabem como lidar com metadados com ID de " "versão menores que os deles." #. (itstool) path: sect2/para #: article.translate.xml:477 msgid "" "Metadata is located in the last sector of the provider (and thus must fit in " "it)." msgstr "" "Os metadados estão localizados no último setor do provedor (e, portanto, " "devem caber nele)." #. (itstool) path: sect2/para #: article.translate.xml:480 msgid "" "(All this is implementation-dependent but all existing code works like that, " "and it is supported by libraries.)" msgstr "" "(Tudo isso depende da implementação, mas todo o código existente funciona " "assim, e é suportado por bibliotecas.)" #. (itstool) path: sect2/title #: article.translate.xml:486 msgid "Labeling/creating a GEOM" msgstr "Rotulando/criando um GEOM" #. (itstool) path: sect2/para #: article.translate.xml:488 msgid "The sequence of events is:" msgstr "A sequência de eventos é:" #. (itstool) path: listitem/para #: article.translate.xml:492 msgid "" "user calls geom8 utility (or one of its hardlinked friends)" msgstr "" "o usuário chama o utilitário geom8 (ou um de seus " "equivalentes hardlinked)" #. (itstool) path: listitem/para #: article.translate.xml:497 msgid "" "the utility figures out which geom class it is supposed to handle and " "searches for geom_CLASSNAME.so library (usually in /lib/geom)." msgstr "" "o utilitário descobre qual classe geom ele é suposto manipular e procura " "pela biblioteca geom_CLASSNAME.so (geralmente em /lib/geom)." #. (itstool) path: listitem/para #: article.translate.xml:505 msgid "" "it dlopen3-s the library, extracts the definitions of command-" "line parameters and helper functions." msgstr "" "ele dlopen3-s a biblioteca, extrai as definições dos " "parâmetros da linha de comandos e funções auxiliares." #. (itstool) path: sect2/para #: article.translate.xml:511 msgid "In the case of creating/labeling a new geom, this is what happens:" msgstr "No caso da criação/rotulação de um novo geom, isso é o que acontece:" #. (itstool) path: listitem/para #: article.translate.xml:516 msgid "" "geom8 looks in the command-line argument for the command (usually " "), and calls a helper function." msgstr "" "O geom8 procura no argumento da linha de comando pelo comando " "(geralmente ) e chama uma função auxiliar ." #. (itstool) path: listitem/para #: article.translate.xml:522 msgid "" "The helper function checks parameters and gathers metadata, which it " "proceeds to write to all concerned providers." msgstr "" "A função auxiliar verifica parâmetros e reúne metadados, que são gravados em " "todos os provedores envolvidos." #. (itstool) path: listitem/para #: article.translate.xml:528 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 "" "Este estraga geoms existentes (se existirem) e inicializa uma " "nova rodada de degustação dos provedores. A classe geom " "pretendida reconhece os metadados e carrega o geom." #. (itstool) path: sect2/para #: article.translate.xml:535 msgid "" "(The above sequence of events is implementation-dependent but all existing " "code works like that, and it is supported by libraries.)" msgstr "" "(A sequência de eventos acima é dependente da implementação, mas todo o " "código existente funciona assim, e é suportado pelas bibliotecas.)" #. (itstool) path: sect2/title #: article.translate.xml:541 msgid "GEOM Command Structure" msgstr "Estrutura do Comando GEOM" #. (itstool) path: sect2/para #: article.translate.xml:543 msgid "" "The helper 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 "" "A biblioteca helper geom_CLASSNAME.so exporta a " "estrutura class_commands, que é uma " "matriz dos elementos struct g_command. Os comandos são uniformes no formato e se parecem com:" #. (itstool) path: sect2/programlisting #: article.translate.xml:548 #, no-wrap msgid " verb [-options] geomname [other]" msgstr " verb [-options] geomname [other]" #. (itstool) path: sect2/para #: article.translate.xml:550 msgid "Common verbs are:" msgstr "Verbos comuns são:" #. (itstool) path: listitem/para #: article.translate.xml:554 msgid "" "label — to write metadata to devices so they can be recognized at tasting " "and brought up in geoms" msgstr "" "label - para gravar metadados em dispositivos para que eles possam ser " "reconhecidos em degustações e criados em geoms" #. (itstool) path: listitem/para #: article.translate.xml:560 msgid "destroy — to destroy metadata, so the geoms get destroyed" msgstr "destroy - para destruir metadados, para que as geoms sejam destruídas" #. (itstool) path: sect2/para #: article.translate.xml:565 msgid "Common options are:" msgstr "Opções comuns são:" #. (itstool) path: listitem/para #: article.translate.xml:569 msgid "-v : be verbose" msgstr "-v : be verbose" #. (itstool) path: listitem/para #: article.translate.xml:573 msgid "-f : force" msgstr "-f : force" #. (itstool) path: sect2/para #: article.translate.xml:577 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 .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 "" "Muitas ações, como rotular e destruir metadados, podem ser executadas no " "userland. Para isso, struct g_command fornece o campo gc_func que pode ser definido " "para uma função (no mesmo .so) que será chamada para " "processar um verbo. Se gc_func for NULL, o comando será " "passado para o módulo do kernel, para a função .ctlreq " "da classe geom." #. (itstool) path: sect2/title #: article.translate.xml:588 msgid "Geoms" msgstr "Geoms" #. (itstool) path: sect2/para #: article.translate.xml:590 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 "" "Geoms são instâncias de classes GEOM. Eles possuem dados internos (uma " "estrutura softc) e algumas funções com as quais eles respondem a eventos " "externos." #. (itstool) path: sect2/para #: article.translate.xml:594 msgid "The event functions are:" msgstr "As funções de evento são:" #. (itstool) path: listitem/para #: article.translate.xml:598 msgid "" ".access : calculates permissions (read/write/exclusive)" msgstr "" ".acess: calcula permissões (leitura / escrita / " "exclusiva)" #. (itstool) path: listitem/para #: article.translate.xml:603 msgid "" ".dumpconf : returns XML-formatted information about the " "geom" msgstr "" ".dumpconf: retorna informações formatadas em XML sobre " "o geom" #. (itstool) path: listitem/para #: article.translate.xml:608 msgid "" ".orphan : called when some underlying provider gets " "disconnected" msgstr "" ".orphan: chamado quando algum provedor subjacente é " "desconectado" #. (itstool) path: listitem/para #: article.translate.xml:613 msgid "" ".spoiled : called when some underlying provider gets " "written to" msgstr "" ".spoiled: chamado quando algum provedor subjacente é " "gravado" #. (itstool) path: listitem/para #: article.translate.xml:618 msgid ".start : handles I/O" msgstr ".start: lida com I/O" #. (itstool) path: sect2/para #: article.translate.xml:622 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 funções são chamadas a partir da thread g_down do " "kernel e não pode haver sleeping neste contexto, (veja a definição de " "sleeping em outro lugar) o que limita um pouco o que pode ser feito, mas " "força o manuseio a ser rápido ." #. (itstool) path: sect2/para #: article.translate.xml:628 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 "" "Destes, a função mais importante para fazer o trabalho útil real é a função " ".start(), que é chamada quando uma requisição BIO chega " "para um provedor gerenciado por uma instância da classe geom." #. (itstool) path: sect2/title #: article.translate.xml:635 msgid "GEOM Threads" msgstr "Threads GEOM" #. (itstool) path: sect2/para #: article.translate.xml:637 msgid "There are three kernel threads created and run by the GEOM framework:" msgstr "" "Existem três threads de kernel criados e executados pelo framework GEOM:" #. (itstool) path: listitem/para #: article.translate.xml:642 msgid "" "g_down : Handles requests coming from high-level entities " "(such as a userland request) on the way to physical devices" msgstr "" "g_down : trata de solicitações provenientes de entidades " "de alto nível (como uma solicitação do userland) no caminho para " "dispositivos físicos" #. (itstool) path: listitem/para #: article.translate.xml:648 msgid "" "g_up : Handles responses from device drivers to requests " "made by higher-level entities" msgstr "" "g_up : lida com respostas de drivers de dispositivos para " "solicitações feitas por entidades de nível superior" #. (itstool) path: listitem/para #: article.translate.xml:654 msgid "" "g_event : Handles all other cases: creation of geom " "instances, access counting, spoil events, etc." msgstr "" "g_event : lida com todos os outros casos: criação de " "instâncias geom, contagem de acessos, eventos spoil, etc." #. (itstool) path: sect2/para #: article.translate.xml:660 msgid "" "When a user process issues read data X at offset Y of a file " "request, this is what happens:" msgstr "" "Quando um processo do usuário emite um pedido de leitura de dados X " "no deslocamento Y de um arquivo, isto é o que acontece:" #. (itstool) path: listitem/para #: article.translate.xml:665 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 "" "O sistema de arquivos converte o pedido em uma instância struct bio e o " "transmite para o subsistema GEOM. Ele sabe o que a instância geom deve " "manipular porque os sistemas de arquivos são hospedados diretamente em uma " "instância geom." #. (itstool) path: listitem/para #: article.translate.xml:672 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 "" "A requisição termina como uma chamada para a função .start() feita para a thread g_down e atinge a instância geom de nível " "superior." #. (itstool) path: listitem/para #: article.translate.xml:679 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 "" "Essa instância geom de nível superior (por exemplo, o segmentador de " "partições) determina que a solicitação deve ser roteada para uma instância " "de nível inferior (por exemplo, o driver de disco). Ele faz uma cópia da " "solicitação bio (solicitações bio SEMPRE precisam ser " "copiadas entre instâncias, com g_clone_bio()!), " "modifica os campos de dados offset e de provedor de destino e executa a " "cópia com g_io_request()" #. (itstool) path: listitem/para #: article.translate.xml:691 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 "" "O driver de disco obtém a solicitação bio também como uma chamada para " ".start() na thread g_down. Ela fala " "com o hardware, recupera os dados e chama g_io_deliver() na bio." #. (itstool) path: listitem/para #: article.translate.xml:700 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 "" "Agora, a notificação de bio conclusão borbulha na thread " "g_up. Primeiro, o slicer de partição obtém ." "done() chamado na thread g_up, ele usa as " "informações armazenadas na bio para liberar a estrutura bio clonada (com g_destroy_bio()) e chama g_io_deliver() no pedido original." #. (itstool) path: listitem/para #: article.translate.xml:711 msgid "The filesystem gets the data and transfers it to userland." msgstr "O sistema de arquivos obtém os dados e os transfere para o usuário." #. (itstool) path: sect2/para #: article.translate.xml:716 msgid "" "See g_bio9 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 "" "Veja a página de manual para o g_bio9 para obter informações " "sobre como os dados são passados para frente e para trás na estrutura " "bio (observe em particular os campos " "bio_parent e bio_children e como eles " "são manipulados)." #. (itstool) path: sect2/para #: article.translate.xml:722 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 "" "Uma característica importante: NAS THREADS G_UP E G_DOWN NÃO SE " "PODE DORMIR (SELEEPING). Isso significa que nenhuma das seguintes " "coisas pode ser feita nessas threads (a lista não é completa, mas apenas " "informativa):" #. (itstool) path: listitem/para #: article.translate.xml:730 msgid "" "Calls to msleep() and tsleep(), " "obviously." msgstr "" "Chamadas para msleep() e tsleep(), " "obviamente." #. (itstool) path: listitem/para #: article.translate.xml:736 msgid "" "Calls to g_write_data() and g_read_data(), because these sleep between passing the data to consumers and " "returning." msgstr "" "Chamadas para g_write_data() e g_read_data(), porque estes dormem entre passar os dados para os consumidores " "e retornar." #. (itstool) path: listitem/para #: article.translate.xml:743 msgid "Waiting for I/O." msgstr "Esperando I/O." #. (itstool) path: listitem/para #: article.translate.xml:747 msgid "" "Calls to malloc9 and uma_zalloc() with " "M_WAITOK flag set" msgstr "" "Chamadas para malloc9 e " "uma_zalloc() com o conjunto de flags M_WAITOK" #. (itstool) path: listitem/para #: article.translate.xml:753 msgid "sx and other sleepable locks" msgstr "sx e outros sleepable locks" #. (itstool) path: sect2/para #: article.translate.xml:757 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 restrição está aqui para impedir que o código GEOM obstrua o caminho da " "solicitação de I/O, já que sleeping normalmente não é limitado pelo tempo e " "não pode haver garantias sobre quanto tempo levará (também existem algumas " "outras razões mais técnicas). Isso também significa que não existe muito o " "que possa ser feito nessas threads; por exemplo, quase qualquer coisa " "complexa requer alocação de memória. Felizmente, existe uma saída: criar " "threads adicionais no kernel." #. (itstool) path: sect2/title #: article.translate.xml:768 msgid "Kernel Threads for Use in GEOM Code" msgstr "Threads de kernel para uso no código GEOM" #. (itstool) path: sect2/para #: article.translate.xml:770 msgid "" "Kernel threads are created with kthread_create9 function, and they are " "sort of similar to userland threads in behavior, only they cannot return to " "caller to signify termination, but must call " "kthread_exit9." msgstr "" "As threads do kernel são criadas com a função " "kthread_create9, e elas são semelhantes aos threads do userland no " "comportamento, eles somente não podem retornar ao chamador para exprimir a " "conclusão, mas deve chamar kthread_exit9." #. (itstool) path: sect2/para #: article.translate.xml:775 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 "" "No código GEOM, o uso usual de threads é para descarregar o processamento de " "requisições da thread g_down (a função .start). Estas threads se parecem com um event handlers: " "elas têm uma lista encadeada de eventos associados a elas (nos quais eventos " "podem ser postados por várias funções em várias threads, portanto, devem ser " "protegidos por um mutex), pegam os eventos da lista, um por um, e processa-" "os em uma grande instrução switch()." #. (itstool) path: sect2/para #: article.translate.xml:785 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 "" "A principal vantagem de usar uma thread para lidar com solicitações de I/O é " "que ela pode dormir quando necessário. Agora, isso parece bom, mas deve ser " "cuidadosamente pensado. Dormir é bom e muito conveniente, mas pode ser muito " "efetivo em destruir o desempenho da transformação geom. As classes " "extremamente sensíveis ao desempenho provavelmente devem fazer todo o " "trabalho na chamada de função .start(), tomando muito " "cuidado para lidar com erros de falta de memória e similares." #. (itstool) path: sect2/para #: article.translate.xml:794 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 "" "O outro benefício de ter uma thread de manipulação de eventos como essa é " "serializar todas as solicitações e respostas provenientes de diferentes " "threads geom em uma thread. Isso também é muito conveniente, mas pode ser " "lento. Na maioria dos casos, o tratamento de pedidos .done() pode ser deixado para a thread g_up." #. (itstool) path: sect2/para #: article.translate.xml:801 msgid "" "Mutexes in FreeBSD kernel (see mutex9) 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, " "sx9 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 "" "Mutexes no kernel do FreeBSD (veja mutex9) têm uma distinção de " "seus primos mais comuns do userland - o código não pode dormir enquanto " "estiver segurando um mutex). Se o código precisar dormir muito, os bloqueios " "sx9 podem ser mais apropriados. Por outro lado, se você faz quase " "tudo em um único thread, você pode se safar sem utilizar mutexes."