The translation is temporarily closed for contributions due to maintenance, please come back later.


(itstool) path: sect4/para
For this reason <function>kern_open</function> and <function>vn_open</function> must be altered to incorporate the additional <varname>dirfd</varname> parameter. No compat layer is created for those because there are not many users of this and the users can be easily converted. This general implementation enables FreeBSD to implement their own *at syscalls. This is being discussed right now.
Context English Portuguese (Brazil) State
The atomic operation takes two parameters <varname>encoded_op</varname> and <varname>uaddr</varname>. The encoded operation encodes the operation itself, comparing value, operation argument, and comparing argument. The pseudocode for the operation is like this one: A operação atômica usa dois parâmetros <varname>encoded_op</varname> e <varname>uaddr</varname>. A operação codificada, codifica a operação em si, comparando valor, argumento de operação e argumento de comparação. O pseudocódigo da operação é como este:
oldval = *uaddr2
*uaddr2 = oldval OP oparg
oldval = *uaddr2
*uaddr2 = oldval OP oparg
And this is done atomically. First a copying in of the number at <varname>uaddr</varname> is performed and the operation is done. The code handles page faults and if no page fault occurs <varname>oldval</varname> is compared to <varname>cmparg</varname> argument with cmp comparator. E isso é feito atomicamente. Primeiro, uma cópia do número em <varname>uaddr</varname> é executada e a operação é concluída. O código manipula falhas de página e, se nenhuma falha de página ocorrer, <varname>oldval</varname> é comparado ao argumento <varname>cmparg</varname> com o comparador cmp.
Futex locking Bloqueio Futex
Futex implementation uses two lock lists protecting <function>sx_lock</function> and global locks (either Giant or another <function>sx_lock</function>). Every operation is performed locked from the start to the very end. A implementação do Futex usa duas listas de lock que protegndo <function>sx_lock</function> e locks globais (Giant ou outra <function>sx_lock</function>). Cada operação é executada bloqueada desde o início até o final.
Various syscalls implementation Implementação de várias syscalls
In this section I am going to describe some smaller syscalls that are worth mentioning because their implementation is not obvious or those syscalls are interesting from other point of view. Nesta seção, descreverei algumas syscalls menores que merecem destaque, pois sua implementação não é óbvia ou as syscalls são interessantes de outro ponto de vista.
*at family of syscalls *na família de syscalls
During development of <trademark class="registered">Linux</trademark> 2.6.16 kernel, the *at syscalls were added. Those syscalls (<function>openat</function> for example) work exactly like their at-less counterparts with the slight exception of the <varname>dirfd</varname> parameter. This parameter changes where the given file, on which the syscall is to be performed, is. When the <varname>filename</varname> parameter is absolute <varname>dirfd</varname> is ignored but when the path to the file is relative, it comes to the play. The <varname>dirfd</varname> parameter is a directory relative to which the relative pathname is checked. The <varname>dirfd</varname> parameter is a file descriptor of some directory or <literal>AT_FDCWD</literal>. So for example the <function>openat</function> syscall can be like this: Durante o desenvolvimento do kernel 2.6.16 do <trademark class="registered">Linux</trademark>, os *at syscalls foram adicionados. Essas syscalls (<function>openat</function>, por exemplo) funcionam exatamente como suas contrapartes sem-menos, com a pequena exceção do parâmetro <varname>dirfd</varname>. Este parâmetro muda onde o arquivo dado, no qual a syscall deve ser executado, está. Quando o parâmetro <varname>filename</varname> é absoluto <varname>dirfd</varname> é ignorado, mas quando o caminho para o arquivo é relativo, ele é checado. O parâmetro <varname>dirfd</varname> é um diretório relativo ao qual o nome do caminho relativo é verificado. O parâmetro <varname>dirfd</varname> é um file descriptor de algum diretório ou <literal>AT_FDCWD</literal>. Então, por exemplo, a syscall <function>openat</function> pode ser assim:
file descriptor 123 = /tmp/foo/, current working directory = /tmp/

openat(123, /tmp/bah\, flags, mode) /* opens /tmp/bah */
openat(123, bah\, flags, mode) /* opens /tmp/foo/bah */
openat(AT_FDWCWD, bah\, flags, mode) /* opens /tmp/bah */
openat(stdio, bah\, flags, mode) /* returns error because stdio is not a directory */
file descriptor 123 = /tmp/foo/, current working directory = /tmp/

openat(123, /tmp/bah\, flags, mode) /* opens /tmp/bah */
openat(123, bah\, flags, mode) /* opens /tmp/foo/bah */
openat(AT_FDWCWD, bah\, flags, mode) /* opens /tmp/bah */
openat(stdio, bah\, flags, mode) /* returns error because stdio is not a directory */
This infrastructure is necessary to avoid races when opening files outside the working directory. Imagine that a process consists of two threads, thread A and thread B. Thread A issues <literal>open(./tmp/foo/bah., flags, mode)</literal> and before returning it gets preempted and thread B runs. Thread B does not care about the needs of thread A and renames or removes <filename>/tmp/foo/</filename>. We got a race. To avoid this we can open <filename>/tmp/foo</filename> and use it as <varname>dirfd</varname> for <function>openat</function> syscall. This also enables user to implement per-thread working directories. Esta infra-estrutura é necessária para evitar corridas ao abrir arquivos fora do diretório de trabalho. Imagine que um processo consiste em duas threads, thread A e thread B. Thread A emite <literal>open (./tmp/foo/bah., Flags, mode)</literal> e antes de retornar ele se antecipa e a thread B é executada. A thread B não se preocupa com as necessidades da thread A e renomeia ou remove o <filename>/tmp/foo/</filename>. Nós temos uma corrida. Para evitar isso, podemos abrir o <filename>/tmp/foo</filename> e usá-lo como <varname>dirfd</varname> para a syscall <function>openat</function>. Isso também permite que o usuário implemente diretórios de trabalho por thread.
<trademark class="registered">Linux</trademark> family of *at syscalls contains: <function>linux_openat</function>, <function>linux_mkdirat</function>, <function>linux_mknodat</function>, <function>linux_fchownat</function>, <function>linux_futimesat</function>, <function>linux_fstatat64</function>, <function>linux_unlinkat</function>, <function>linux_renameat</function>, <function>linux_linkat</function>, <function>linux_symlinkat</function>, <function>linux_readlinkat</function>, <function>linux_fchmodat</function> and <function>linux_faccessat</function>. All these are implemented using the modified <citerefentry><refentrytitle>namei</refentrytitle><manvolnum>9</manvolnum></citerefentry> routine and simple wrapping layer. A família do <trademark class="registered">Linux</trademark> de *at syscalls contém: <function>linux_openat</function>, <function>linux_mkdirat</function>, <function>linux_mknodat</function>, <function>linux_fchownat</function>, <function>linux_futimesat</function>, <function>linux_fstatat64</function>, <function>linux_unlinkat</function>, <function>linux_renameat</function>, <function>linux_linkat</function> , <function>linux_symlinkat</function>, <function>linux_readlinkat</function>, <function>linux_fchmodat</function> e <function>linux_faccessat</function>. Tudo isso é implementado usando a rotina modificada <citerefentry><refentrytitle>namei</refentrytitle><manvolnum>9</manvolnum></citerefentry> e a simples camada de quebra automática.
Implementation Implementação
The implementation is done by altering the <citerefentry><refentrytitle>namei</refentrytitle><manvolnum>9</manvolnum></citerefentry> routine (described above) to take additional parameter <varname>dirfd</varname> in its <literal>nameidata</literal> structure, which specifies the starting point of the pathname lookup instead of using the current working directory every time. The resolution of <varname>dirfd</varname> from file descriptor number to a vnode is done in native *at syscalls. When <varname>dirfd</varname> is <literal>AT_FDCWD</literal> the <varname>dvp</varname> entry in <literal>nameidata</literal> structure is <literal>NULL</literal> but when <varname>dirfd</varname> is a different number we obtain a file for this file descriptor, check whether this file is valid and if there is vnode attached to it then we get a vnode. Then we check this vnode for being a directory. In the actual <citerefentry><refentrytitle>namei</refentrytitle><manvolnum>9</manvolnum></citerefentry> routine we simply substitute the <varname>dvp</varname> vnode for <varname>dp</varname> variable in the <citerefentry><refentrytitle>namei</refentrytitle><manvolnum>9</manvolnum></citerefentry> function, which determines the starting point. The <citerefentry><refentrytitle>namei</refentrytitle><manvolnum>9</manvolnum></citerefentry> is not used directly but via a trace of different functions on various levels. For example the <function>openat</function> goes like this: A implementação é feita alterando a rotina <citerefentry><refentrytitle>namei</refentrytitle><manvolnum>9</manvolnum></citerefentry> (descrita acima) para obter o parâmetro adicional <varname>dirfd</varname> no sua estrutura <literal>nameidata</literal> , que especifica o ponto inicial da pesquisa do nome do caminho, em vez de usar o diretório de trabalho atual todas as vezes. A resolução de <varname>dirfd</varname> do número do file descriptor para um vnode é feita em *at syscalls nativo. Quando <varname>dirfd</varname> é <literal>AT_FDCWD</literal>, a entrada <varname>dvp</varname> na estrutura <literal>nameidata</literal> é <literal>NULL</literal>, mas <varname>dirfd</varname> é um número diferente, obtemos um arquivo para este file descriptor, verificamos se este arquivo é válido e se há vnode anexado a ele, então obtemos um vnode. Então nós verificamos este vnode por ser um diretório. Na rotina real <citerefentry><refentrytitle>namei</refentrytitle><manvolnum>9</manvolnum></citerefentry> simplesmente substituímos a variável <varname>dvp</varname> vnode pela variável <varname>dp</varname> na função <citerefentry><refentrytitle>namei</refentrytitle><manvolnum>9</manvolnum></citerefentry>, que determina o ponto de partida. O <citerefentry><refentrytitle>namei</refentrytitle><manvolnum>9</manvolnum></citerefentry> não é usado diretamente, mas através de um rastreamento de diferentes funções em vários níveis. Por exemplo, o <function>openat</function> é assim:
openat() --&gt; kern_openat() --&gt; vn_open() -&gt; namei() openat() --&gt; kern_openat() --&gt; vn_open() -&gt; namei()
For this reason <function>kern_open</function> and <function>vn_open</function> must be altered to incorporate the additional <varname>dirfd</varname> parameter. No compat layer is created for those because there are not many users of this and the users can be easily converted. This general implementation enables FreeBSD to implement their own *at syscalls. This is being discussed right now. Por esse motivo, <function>kern_open</function> e <function>vn_open</function> devem ser alterados para incorporar o parâmetro <varname>dirfd</varname> adicional. Nenhuma camada de compatibilidade é criada para esses, porque não há muitos usuários disso e os usuários podem ser facilmente convertidos. Esta implementação geral permite ao FreeBSD implementar suas próprias *at syscalls. Isso está sendo discutido agora.
Ioctl Ioctl
The ioctl interface is quite fragile due to its generality. We have to bear in mind that devices differ between <trademark class="registered">Linux</trademark> and FreeBSD so some care must be applied to do ioctl emulation work right. The ioctl handling is implemented in <filename>linux_ioctl.c</filename>, where <function>linux_ioctl</function> function is defined. This function simply iterates over sets of ioctl handlers to find a handler that implements a given command. The ioctl syscall has three parameters, the file descriptor, command and an argument. The command is a 16-bit number, which in theory is divided into high 8 bits determining class of the ioctl command and low 8 bits, which are the actual command within the given set. The emulation takes advantage of this division. We implement handlers for each set, like <function>sound_handler</function> or <function>disk_handler</function>. Each handler has a maximum command and a minimum command defined, which is used for determining what handler is used. There are slight problems with this approach because <trademark class="registered">Linux</trademark> does not use the set division consistently so sometimes ioctls for a different set are inside a set they should not belong to (SCSI generic ioctls inside cdrom set, etc.). FreeBSD currently does not implement many <trademark class="registered">Linux</trademark> ioctls (compared to NetBSD, for example) but the plan is to port those from NetBSD. The trend is to use <trademark class="registered">Linux</trademark> ioctls even in the native FreeBSD drivers because of the easy porting of applications. A interface ioctl é bastante frágil devido à sua generalidade. Nós temos que ter em mente que os dispositivos diferem entre <trademark class="registered">Linux</trademark> e FreeBSD, então alguns cuidados devem ser aplicados para fazer o trabalho de emulação de ioctl corretamente. O manuseio ioctl é implementado em <filename>linux_ioctl.c</filename>, onde a função <function>linux_ioctl</function> é definida. Esta função simplesmente itera sobre conjuntos de manipuladores ioctl para encontrar um manipulador que implementa um dado comando. A syscall ioctl tem três parâmetros, o file descriptor, comando e um argumento. O comando é um número de 16 bits, que, em teoria, é dividido em alta classe determinante de 8 bits do comando ioctl e 8 bits baixos, que são o comando real dentro do conjunto dado. A emulação aproveita essa divisão. Implementamos manipuladores para cada conjunto, como <function>sound_handler</function> ou <function>disk_handler</function>. Cada manipulador tem um comando máximo e um comando mínimo definido, que é usado para determinar qual manipulador é usado. Existem pequenos problemas com esta abordagem porque <trademark class="registered">Linux</trademark> não usa a divisão definida consistentemente, por isso as ioctls para um conjunto diferente estão dentro de um conjunto ao qual não devem pertencer (ioctls genéricos SCSI dentro do cdrom conjunto, etc.). O FreeBSD atualmente não implementa muitos ioctls do <trademark class="registered">Linux</trademark> (comparado ao NetBSD, por exemplo), mas o plano é portar os do NetBSD. A tendência é usar o ioctls <trademark class="registered">Linux</trademark> mesmo nos drivers nativos do FreeBSD, devido à fácil portabilidade dos aplicativos.
Debugging Depuração
Every syscall should be debuggable. For this purpose we introduce a small infrastructure. We have the ldebug facility, which tells whether a given syscall should be debugged (settable via a sysctl). For printing we have LMSG and ARGS macros. Those are used for altering a printable string for uniform debugging messages. Cada syscall deve ser debugável. Para isso, introduzimos uma pequena infra-estrutura. Nós temos o recurso ldebug, que informa se uma dada syscall deve ser depurada (configurável através de um sysctl). Para impressão, temos as macros LMSG e ARGS. Essas são usadas para alterar uma string imprimível para mensagens uniformes de depuração.
Conclusion Conclusão
Results Resultados
As of April 2007 the <trademark class="registered">Linux</trademark> emulation layer is capable of emulating the <trademark class="registered">Linux</trademark> 2.6.16 kernel quite well. The remaining problems concern futexes, unfinished *at family of syscalls, problematic signals delivery, missing <function>epoll</function> and <function>inotify</function> and probably some bugs we have not discovered yet. Despite this we are capable of running basically all the <trademark class="registered">Linux</trademark> programs included in FreeBSD Ports Collection with Fedora Core 4 at 2.6.16 and there are some rudimentary reports of success with Fedora Core 6 at 2.6.16. The Fedora Core 6 linux_base was recently committed enabling some further testing of the emulation layer and giving us some more hints where we should put our effort in implementing missing stuff. Em abril de 2007, a camada de emulação do <trademark class="registered">Linux</trademark> é capaz de emular o kernel <trademark class="registered">Linux</trademark> 2.6.16 muito bem. Os problemas remanescentes dizem respeito a futexes, inacabado na família de syscalls *at, entrega de sinais problemáticos, falta de <function>epoll</function> e <function>inotify</function> e provavelmente alguns bugs que ainda não descobrimos. Apesar disso, somos capazes de executar basicamente todos os programas <trademark class="registered">Linux</trademark> incluídos na coleção de ports do FreeBSD com o Fedora Core 4 em 2.6.16 e há alguns relatos rudimentares de sucesso com o Fedora Core 6 em 2.6.16. O linux_base do Fedora Core 6 foi recentemente comprometido permitindo alguns testes adicionais da camada de emulação e nos dando mais algumas dicas onde devemos nos esforçar para implementar o material que está faltando.
We are able to run the most used applications like <package>www/linux-firefox</package>, <package>net-im/skype</package> and some games from the Ports Collection. Some of the programs exhibit bad behavior under 2.6 emulation but this is currently under investigation and hopefully will be fixed soon. The only big application that is known not to work is the <trademark class="registered">Linux</trademark> <trademark>Java</trademark> Development Kit and this is because of the requirement of <function>epoll</function> facility which is not directly related to the <trademark class="registered">Linux</trademark> kernel 2.6. Nós podemos rodar os aplicativos mais usados como o <package>www/linux-firefox</package>, <package>net-im/skype</package> e alguns jogos da Coleção de Ports. Alguns dos programas exibem mau comportamento na emulação 2.6, mas isso está atualmente sob investigação e, espera-se, será corrigido em breve. A única grande aplicação que se sabe que não funciona é o <trademark>Java</trademark> Development Kit do <trademark class="registered">Linux</trademark> e isto é devido ao requisito de <function>epoll</function> habilidade que não está diretamente relacionada ao kernel do <trademark class="registered">Linux</trademark> 2.6.
We hope to enable 2.6.16 emulation by default some time after FreeBSD 7.0 is released at least to expose the 2.6 emulation parts for some wider testing. Once this is done we can switch to Fedora Core 6 linux_base, which is the ultimate plan. Esperamos habilitar a emulação 2.6.16 por padrão algum tempo depois que o FreeBSD 7.0 for lançado pelo menos para expor as partes da emulação 2.6 para alguns testes mais amplos. Feito isso, podemos mudar para o Fedora Core 6 linux_base, que é o plano final.
Future work Trabalho futuro
Future work should focus on fixing the remaining issues with futexes, implement the rest of the *at family of syscalls, fix the signal delivery and possibly implement the <function>epoll</function> and <function>inotify</function> facilities. O trabalho futuro deve focar na correção dos problemas remanescentes com futexes, implementar o restante da família de syscalls, corrigir a entrega de sinal e possivelmente implementar os recursos de <function>epoll</function> e <function>inotify</function>.
We hope to be able to run the most important programs flawlessly soon, so we will be able to switch to the 2.6 emulation by default and make the Fedora Core 6 the default linux_base because our currently used Fedora Core 4 is not supported any more. Esperamos poder executar os programas mais importantes com perfeição em breve, por isso poderemos alternar para a emulação 2.6 por padrão e fazer do Fedora Core 6 o linux_base padrão porque o nosso atualmente usado Fedora Core 4 não é mais suportado.
The other possible goal is to share our code with NetBSD and DragonflyBSD. NetBSD has some support for 2.6 emulation but its far from finished and not really tested. DragonflyBSD has expressed some interest in porting the 2.6 improvements. O outro objetivo possível é compartilhar nosso código com o NetBSD e o DragonflyBSD. O NetBSD tem algum suporte para emulação 2.6, mas está longe de ser concluído e não foi realmente testado. O DragonflyBSD manifestou algum interesse em portar as melhorias do 2.6.
Generally, as <trademark class="registered">Linux</trademark> develops we would like to keep up with their development, implementing newly added syscalls. Splice comes to mind first. Some already implemented syscalls are also heavily crippled, for example <function>mremap</function> and others. Some performance improvements can also be made, finer grained locking and others. Geralmente, como o <trademark class="registered">Linux</trademark> se desenvolve, gostaríamos de acompanhar seu desenvolvimento, implementando a syscalls recém-adicionado. Splice vem em mente primeiro. Algumas syscalls já implementadas também são altamente danificadas, por exemplo <function>mremap</function> e outras. Alguns aprimoramentos de desempenho também podem ser feitos, um lock mais refinado e outros.
Team Equipe


No matching activity found.

Browse all component changes


English Portuguese (Brazil)
No related strings found in the glossary.

Source information

Source string comment
(itstool) path: sect4/para
Source string location
String age
a year ago
Source string age
a year ago
Translation file
articles/pt_BR/linux-emulation.po, string 354