Translation

(itstool) path: sect3/para
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.
669/6200
Context English Portuguese (Brazil) State
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.

Loading…

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.
3 months ago
Browse all component changes

Glossary

English Portuguese (Brazil)
Open Source Project Projeto Open Source FreeBSD Doc

Source information

Source string comment
(itstool) path: sect3/para
Labels
No labels currently set.
Source string location
article.translate.xml:2318
Source string age
3 months ago
Translation file
articles/pt_BR/linux-emulation.po, string 349