https://criu.org/index.php?title=How_hard_is_it_to_open_a_file&feed=atom&action=historyHow hard is it to open a file - Revision history2024-03-28T17:49:33ZRevision history for this page on the wikiMediaWiki 1.35.6https://criu.org/index.php?title=How_hard_is_it_to_open_a_file&diff=3587&oldid=prevKir: Intro added2016-09-24T02:57:19Z<p>Intro added</p>
<table class="diff diff-contentalign-left diff-editfont-monospace" data-mw="interface">
<col class="diff-marker" />
<col class="diff-content" />
<col class="diff-marker" />
<col class="diff-content" />
<tr class="diff-title" lang="en">
<td colspan="2" style="background-color: #fff; color: #202122; text-align: center;">← Older revision</td>
<td colspan="2" style="background-color: #fff; color: #202122; text-align: center;">Revision as of 02:57, 24 September 2016</td>
</tr><tr><td colspan="2" class="diff-lineno" id="mw-diff-left-l1" >Line 1:</td>
<td colspan="2" class="diff-lineno">Line 1:</td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;"><div><ins style="font-weight: bold; text-decoration: none;">This article outlines what CRIU restore needs to take care of when re-creating an open file descriptor.</ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;"><div><ins style="font-weight: bold; text-decoration: none;"></ins></div></td></tr>
<tr><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div>Let's imagine we have an information about a file we want to open.</div></td><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div>Let's imagine we have an information about a file we want to open.</div></td></tr>
<tr><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div>What should it contain? Apparently, access mode and path:</div></td><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div>What should it contain? Apparently, access mode and path:</div></td></tr>
</table>Kirhttps://criu.org/index.php?title=How_hard_is_it_to_open_a_file&diff=3474&oldid=prevKir: use source highlighting; fixes and improvements in English2016-09-20T23:42:23Z<p>use source highlighting; fixes and improvements in English</p>
<a href="https://criu.org/index.php?title=How_hard_is_it_to_open_a_file&diff=3474&oldid=2133">Show changes</a>Kirhttps://criu.org/index.php?title=How_hard_is_it_to_open_a_file&diff=2133&oldid=prevXemul: cat files2015-02-26T15:45:42Z<p>cat files</p>
<table class="diff diff-contentalign-left diff-editfont-monospace" data-mw="interface">
<col class="diff-marker" />
<col class="diff-content" />
<col class="diff-marker" />
<col class="diff-content" />
<tr class="diff-title" lang="en">
<td colspan="2" style="background-color: #fff; color: #202122; text-align: center;">← Older revision</td>
<td colspan="2" style="background-color: #fff; color: #202122; text-align: center;">Revision as of 15:45, 26 February 2015</td>
</tr><tr><td colspan="2" class="diff-lineno" id="mw-diff-left-l289" >Line 289:</td>
<td colspan="2" class="diff-lineno">Line 289:</td></tr>
<tr><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"></td><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"></td></tr>
<tr><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div>[[Category:Under the hood]]</div></td><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div>[[Category:Under the hood]]</div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;"><div><ins style="font-weight: bold; text-decoration: none;">[[Category:Files]]</ins></div></td></tr>
</table>Xemulhttps://criu.org/index.php?title=How_hard_is_it_to_open_a_file&diff=1844&oldid=prevXemul at 08:46, 3 December 20142014-12-03T08:46:15Z<p></p>
<table class="diff diff-contentalign-left diff-editfont-monospace" data-mw="interface">
<col class="diff-marker" />
<col class="diff-content" />
<col class="diff-marker" />
<col class="diff-content" />
<tr class="diff-title" lang="en">
<td colspan="2" style="background-color: #fff; color: #202122; text-align: center;">← Older revision</td>
<td colspan="2" style="background-color: #fff; color: #202122; text-align: center;">Revision as of 08:46, 3 December 2014</td>
</tr><tr><td colspan="2" class="diff-lineno" id="mw-diff-left-l39" >Line 39:</td>
<td colspan="2" class="diff-lineno">Line 39:</td></tr>
<tr><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"></td><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"></td></tr>
<tr><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div>Now this seems to be OK, but it's actually not. In Linux file can be</div></td><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div>Now this seems to be OK, but it's actually not. In Linux file can be</div></td></tr>
<tr><td class='diff-marker'>−</td><td style="color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;"><div>unlinked while being opened. In that case what was formerly pointed by</div></td><td class='diff-marker'>+</td><td style="color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;"><div>unlinked while being opened <ins class="diffchange diffchange-inline">(these [[invisible files]] are treated carefully</ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;"><div><ins class="diffchange diffchange-inline">on dump)</ins>. In that case what was formerly pointed by</div></td></tr>
<tr><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div>path may be kept in some temporary location. And we have to create a</div></td><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div>path may be kept in some temporary location. And we have to create a</div></td></tr>
<tr><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div>temp name for it and unlink one afterwards. So we need to extend the</div></td><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div>temp name for it and unlink one afterwards. So we need to extend the</div></td></tr>
</table>Xemulhttps://criu.org/index.php?title=How_hard_is_it_to_open_a_file&diff=1614&oldid=prevXemul at 11:24, 5 August 20142014-08-05T11:24:30Z<p></p>
<table class="diff diff-contentalign-left diff-editfont-monospace" data-mw="interface">
<col class="diff-marker" />
<col class="diff-content" />
<col class="diff-marker" />
<col class="diff-content" />
<tr class="diff-title" lang="en">
<td colspan="2" style="background-color: #fff; color: #202122; text-align: center;">← Older revision</td>
<td colspan="2" style="background-color: #fff; color: #202122; text-align: center;">Revision as of 11:24, 5 August 2014</td>
</tr><tr><td colspan="2" class="diff-lineno" id="mw-diff-left-l285" >Line 285:</td>
<td colspan="2" class="diff-lineno">Line 285:</td></tr>
<tr><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div></pre></div></td><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div></pre></div></td></tr>
<tr><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"></td><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"></td></tr>
<tr><td class='diff-marker'>−</td><td style="color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;"><div>but it's not. <del class="diffchange diffchange-inline">We</del>'<del class="diffchange diffchange-inline">ll get back </del>to <del class="diffchange diffchange-inline">it in the next series.</del></div></td><td class='diff-marker'>+</td><td style="color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;"><div>but it's not. <ins class="diffchange diffchange-inline">Here</ins>'<ins class="diffchange diffchange-inline">s [[how </ins>to <ins class="diffchange diffchange-inline">assign needed file descriptor to a file]] :)</ins></div></td></tr>
<tr><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"></td><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"></td></tr>
<tr><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div>[[Category:Under the hood]]</div></td><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div>[[Category:Under the hood]]</div></td></tr>
</table>Xemulhttps://criu.org/index.php?title=How_hard_is_it_to_open_a_file&diff=1572&oldid=prevXemul: Categorized2014-07-16T13:26:10Z<p>Categorized</p>
<table class="diff diff-contentalign-left diff-editfont-monospace" data-mw="interface">
<col class="diff-marker" />
<col class="diff-content" />
<col class="diff-marker" />
<col class="diff-content" />
<tr class="diff-title" lang="en">
<td colspan="2" style="background-color: #fff; color: #202122; text-align: center;">← Older revision</td>
<td colspan="2" style="background-color: #fff; color: #202122; text-align: center;">Revision as of 13:26, 16 July 2014</td>
</tr><tr><td colspan="2" class="diff-lineno" id="mw-diff-left-l286" >Line 286:</td>
<td colspan="2" class="diff-lineno">Line 286:</td></tr>
<tr><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"></td><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"></td></tr>
<tr><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div>but it's not. We'll get back to it in the next series.</div></td><td class='diff-marker'> </td><td style="background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;"><div>but it's not. We'll get back to it in the next series.</div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;"><div><ins style="font-weight: bold; text-decoration: none;"></ins></div></td></tr>
<tr><td colspan="2"> </td><td class='diff-marker'>+</td><td style="color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;"><div><ins style="font-weight: bold; text-decoration: none;">[[Category:Under the hood]]</ins></div></td></tr>
</table>Xemulhttps://criu.org/index.php?title=How_hard_is_it_to_open_a_file&diff=1571&oldid=prevXemul: Created page with "OK, let's imagine we have an information about a file we want to open. What should it contain? Apparently access mode and path <pre> struct file { char *path; unsigned m..."2014-07-16T11:55:24Z<p>Created page with "OK, let's imagine we have an information about a file we want to open. What should it contain? Apparently access mode and path <pre> struct file { char *path; unsigned m..."</p>
<p><b>New page</b></p><div>OK, let's imagine we have an information about a file we want to open.<br />
What should it contain? Apparently access mode and path<br />
<br />
<pre><br />
struct file {<br />
char *path;<br />
unsigned mode;<br />
} *f;<br />
</pre><br />
<br />
and we'd like to have that path being opened by a process. We would<br />
do it like below:<br />
<br />
<pre><br />
int fd;<br />
<br />
fd = open(f->path, f->mode);<br />
</pre><br />
<br />
right? Right, but it's not all. We all know, that not only regular<br />
files might be opened via paths, but also such things as FIFO-s. And<br />
plain open with the flags we want it to have may just hang. So we need<br />
to change that code to look like this:<br />
<br />
<pre><br />
int fd, tfd = -1;<br />
<br />
if (S_ISFIFO(f->mode))<br />
tfd = open(f->path, O_RDWR);<br />
<br />
fd = open(f->path, f->mode);<br />
<br />
if (tfd >= 0)<br />
close(tfd);<br />
</pre><br />
<br />
The tfd keeps FIFO read-write opened while we open it with any flags<br />
we want. Then we close it.<br />
<br />
Now this seems to be OK, but it's actually not. In Linux file can be<br />
unlinked while being opened. In that case what was formerly pointed by<br />
path may be kept in some temporary location. And we have to create a<br />
temp name for it and unlink one afterwards. So we need to extend the<br />
info about file<br />
<br />
<pre><br />
struct file {<br />
char *path;<br />
unsigned mode;<br />
char *temp_path;<br />
} *f;<br />
</pre><br />
<br />
and the opening code to take care of that temorary location<br />
<br />
<pre><br />
int fd, tfd = -1;<br />
<br />
if (f->temp_path)<br />
link(f->temp_path, f->path);<br />
<br />
if (S_ISFIFO(f->mode))<br />
tfd = open(f->path, O_RDWR);<br />
<br />
fd = open(f->path, f->mode);<br />
<br />
if (tfd >= 0)<br />
close(tfd);<br />
<br />
if (f->temp_path)<br />
unlink(f->path);<br />
</pre><br />
<br />
And we haven't seen all the code we need to manage what is pointed by<br />
the temp_path, but let's proceed.<br />
<br />
We have forgotten, that opened and unl^w removed can also be a<br />
directory. On directories link and unlink do not work and we have to<br />
slightly fix the code to at least try to make things work OK:<br />
<br />
<pre><br />
int fd, tfd = -1;<br />
<br />
if (f->temp_path) {<br />
if (S_ISDIR(f->mode))<br />
mkdir(f->path);<br />
else<br />
link(f->temp_path, f->path);<br />
}<br />
<br />
if (S_ISFIFO(f->mode))<br />
tfd = open(f->path, O_RDWR);<br />
<br />
fd = open(f->path, f->mode);<br />
<br />
if (tfd >= 0)<br />
close(tfd);<br />
<br />
if (f->temp_path) {<br />
if (S_ISDIR(f->mode))<br />
rmdir(f->mode);<br />
else<br />
unlink(f->path);<br />
}<br />
</pre><br />
<br />
Done. But, we also should take care of hard links. If a file has such<br />
and both were opened and removed, we cannot after opening just go<br />
ahead and kill the temp_path -- it can be waiting for some other<br />
struct file to open one. A little bit more information should be added<br />
to the struct file<br />
<br />
<pre><br />
struct temp_file {<br />
char *path;<br />
unsigned users;<br />
};<br />
<br />
struct file {<br />
char *path;<br />
unsigned mode;<br />
struct temp_file *temp;<br />
} *f;<br />
</pre><br />
<br />
and to the code that opens one now looks like this:<br />
<br />
<pre><br />
int fd, tfd = -1;<br />
<br />
if (f->temp) {<br />
if (S_ISDIR(f->mode))<br />
mkdir(f->path);<br />
else<br />
link(f->temp->path, f->path);<br />
}<br />
<br />
if (S_ISFIFO(f->mode))<br />
tfd = open(f->path, O_RDWR);<br />
<br />
fd = open(f->path, f->mode);<br />
<br />
if (tfd >= 0)<br />
close(tfd);<br />
<br />
if (f->temp) {<br />
if (--f->temp->users == 0) {<br />
if (S_ISDIR(f->mode))<br />
rmdir(f->mode);<br />
else<br />
unlink(f->temp->path);<br />
}<br />
}<br />
</pre><br />
<br />
By the way, we've left behind the scenes all the code required to make<br />
the temp_file data be shared between processes that need one and to<br />
make the decrement of f->temp->users be smp-safe.<br />
<br />
Also note, that we don't handle the case when the file/directory is<br />
removed and some other file/directory is created under the same name.<br />
It's rare case.<br />
<br />
Now, is that all? No, sorry. A couple of things left. First, Linux has<br />
a thing called mount namespace. And two files with the same path may<br />
have been opened in different mount namespaces. So we also need the<br />
info about what mount point the file belongs to like this:<br />
<br />
<pre><br />
struct file {<br />
char *path;<br />
unsigned mode;<br />
struct temp_file *temp;<br />
unsigned mnt_id;<br />
} *f;<br />
</pre><br />
<br />
and the code to open file would now look like<br />
<br />
<pre><br />
int fd, tfd = -1, ns_fd;<br />
char *rel_path = f->path + 1;<br />
<br />
ns_fd = open_ns_root(f->mnt_id);<br />
<br />
if (f->temp) {<br />
if (S_ISDIR(f->mode))<br />
mkdirat(ns_fd, rel_path);<br />
else<br />
linkat(ns_fd, f->temp->path, ns_fd, rel_path);<br />
}<br />
<br />
if (S_ISFIFO(f->mode))<br />
tfd = openat(ns_fd, rel_path, O_RDWR);<br />
<br />
fd = openat(ns_fd, rel_path, f->mode);<br />
<br />
if (tfd >= 0)<br />
close(tfd);<br />
<br />
if (f->temp_path) {<br />
if (--f->temp->users == 0) {<br />
if (S_ISDIR(f->mode))<br />
unlinkat(ns_fd, f->mode, AT_REMOVEDIR);<br />
else<br />
unlinkat(ns_fd, f->temp->path);<br />
}<br />
}<br />
<br />
close(ns_fd);<br />
</pre><br />
<br />
Let me not dive into the details of how the open_ns_root looks like.<br />
Just know, that it opens a file descriptor, that refers to the root<br />
of the mount namespace that contains a mount point with the id mnt_id<br />
(they cannot be shared, and that's great).<br />
<br />
Pretty complex already, isn't it? Just a couple of final touches left.<br />
First, opened files typically have a position. Flags we get need to be<br />
sanitated not to container those that only make sense during open,<br />
like O_TRUNC or O_CREAT. And file may have a thing called fown managed<br />
by the F_SETSIG and F_SETOWN fcntls. All this results in<br />
<br />
<pre><br />
struct file {<br />
char *path;<br />
unsigned mode;<br />
struct temp_file *temp;<br />
unsigned mnt_id;<br />
unsigned long pos;<br />
struct fown fown;<br />
} *f;<br />
</pre><br />
<br />
and<br />
<br />
<pre><br />
int fd, tfd = -1, ns_fd, open_flags;<br />
char *rel_path = f->path + 1;<br />
<br />
ns_fd = open_ns_root(f->mnt_id);<br />
<br />
if (f->temp) {<br />
if (S_ISDIR(f->mode))<br />
mkdirat(ns_fd, rel_path);<br />
else<br />
linkat(ns_fd, f->temp->path, ns_fd, rel_path);<br />
}<br />
<br />
if (S_ISFIFO(f->mode))<br />
tfd = openat(ns_fd, rel_path, O_RDWR);<br />
<br />
open_flags = sanitize_open_mode(f->mode);<br />
fd = openat(ns_fd, rel_path, open_flags);<br />
<br />
if (tfd >= 0)<br />
close(tfd);<br />
<br />
if (f->temp_path) {<br />
if (--f->temp->users == 0) {<br />
if (S_ISDIR(f->mode))<br />
unlinkat(ns_fd, f->mode, AT_REMOVEDIR);<br />
else<br />
unlinkat(ns_fd, f->temp->path);<br />
}<br />
}<br />
<br />
close(ns_fd);<br />
<br />
fcntl(fd, F_SETSIG, f->fown->sig);<br />
fcntl(fd, F_SETOWN, &f->fown->owner);<br />
lseek(fd, SEEK_SET, f->pos);<br />
</pre><br />
<br />
And don't ask for details of the f->fown thing. It's tricky, but just<br />
follows the ABI and thus boring.<br />
<br />
OK, we've finished with the top of the iceberg -- opening a file. Why<br />
top? Becase when opened file should be planted into a process' file<br />
descriptors table under desired number. You might thing, that it's as<br />
simple as<br />
<br />
<pre><br />
dup2(fd, desired_fd);<br />
</pre><br />
<br />
but it's not. We'll get back to it in the next series.</div>Xemul