Source string Read only

(itstool) path: sect3/para
620/6200
Context English State
Various syscalls implementation
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.
*at family of 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:
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.
<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.
Implementation
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:
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.

Loading…

None

New source string

FreeBSD Doc / articles_linux-emulationEnglish

New source string 3 months ago
Browse all component changes

Things to check

Long untranslated

The string was not translated for a long time

Reset

Glossary

English English
No related strings found in the glossary.

Source information

Source string comment
(itstool) path: sect3/para
Labels
No labels currently set.
Flags
read-only
Source string location
article.translate.xml:2318
Source string age
3 months ago
Translation file
, string 349