<div dir="ltr">Anyway, as is we can simply enable opts.overlayfs = true always, and make sure that __mntns_get_root_fd and fstatat get called only if there is an OverlayFS entry in the mountinfo table. What do you think of that?</div><div class="gmail_extra"><br><div class="gmail_quote">2015-08-05 15:06 GMT-07:00 Gabriel Guimaraes <span dir="ltr">&lt;<a href="mailto:gabriellimaguimaraes@gmail.com" target="_blank">gabriellimaguimaraes@gmail.com</a>&gt;</span>:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Hmm, I&#39;m using GDB to look directly at the value of p-&gt;fs_type within fill_fdlink, when p refers to a file within a Docker container mounted with Overlayfs and I get <span style="font-size:12.8000001907349px">p-&gt;fs_type = 0xef53</span></div><div class="HOEnZb"><div class="h5"><div class="gmail_extra"><br><div class="gmail_quote">2015-08-05 14:36 GMT-07:00 Filipe Brandenburger <span dir="ltr">&lt;<a href="mailto:filbranden@google.com" target="_blank">filbranden@google.com</a>&gt;</span>:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">More specifically, I&#39;m looking at this code:<br>
<br>
/**<br>
 * ovl_statfs<br>
 * @sb: The overlayfs super block<br>
 * @buf: The struct kstatfs to fill in with stats<br>
 *<br>
 * Get the filesystem statistics.  As writes always target the upper layer<br>
 * filesystem pass the statfs to the same filesystem.<br>
 */<br>
static int ovl_statfs(struct dentry *dentry, struct kstatfs *buf)<br>
{<br>
        struct ovl_fs *ofs = dentry-&gt;d_sb-&gt;s_fs_info;<br>
        struct dentry *root_dentry = dentry-&gt;d_sb-&gt;s_root;<br>
        struct path path;<br>
        int err;<br>
<br>
        ovl_path_upper(root_dentry, &amp;path);<br>
<br>
        err = vfs_statfs(&amp;path, buf);<br>
        if (!err) {<br>
                buf-&gt;f_namelen = max(buf-&gt;f_namelen, ofs-&gt;lower_namelen);<br>
                buf-&gt;f_type = OVERLAYFS_SUPER_MAGIC;<br>
        }<br>
<br>
        return err;<br>
}<br>
<br>
<br>
So, indeed, it&#39;s forwarding the call to the upper layer (since it&#39;s<br>
where writes happen) but before returning it&#39;s overwriting f_type with<br>
OVERLAYFS_SUPER_MAGIC which is the constant with the value I posted<br>
above...<br>
<br>
Cheers,<br>
Filipe<br>
<div><div><br>
<br>
On Wed, Aug 5, 2015 at 2:34 PM, Filipe Brandenburger<br>
&lt;<a href="mailto:filbranden@google.com" target="_blank">filbranden@google.com</a>&gt; wrote:<br>
&gt; Can you try a directory instead of a file?<br>
&gt;<br>
&gt; Either a subdirectory or the root of the filesystem (where it&#39;s mounted.)<br>
&gt;<br>
&gt;<br>
&gt; On Wed, Aug 5, 2015 at 2:31 PM, Gabriel Guimaraes<br>
&gt; &lt;<a href="mailto:gabriellimaguimaraes@gmail.com" target="_blank">gabriellimaguimaraes@gmail.com</a>&gt; wrote:<br>
&gt;&gt; Hi Filipe,<br>
&gt;&gt;<br>
&gt;&gt; I just checked the value of p-&gt;fs_type when referring to /tmp/file within a<br>
&gt;&gt; Docker container, using overlayFS. It reports<br>
&gt;&gt;<br>
&gt;&gt; p-&gt;fs_type = 0xef53 which I believe is the magic number of ext2/3/4<br>
&gt;&gt;<br>
&gt;&gt; 2015-08-05 14:25 GMT-07:00 Filipe Brandenburger &lt;<a href="mailto:filbranden@google.com" target="_blank">filbranden@google.com</a>&gt;:<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt; Hi Gabriel,<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt; Looking at the code, I believe it f_type in statfs() output will<br>
&gt;&gt;&gt; return this value for overlayfs:<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt; fs/overlayfs/super.c:#define OVERLAYFS_SUPER_MAGIC 0x794c7630<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt; You can easily double check that with a test program running it<br>
&gt;&gt;&gt; against a mounted overlayfs.<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt; Cheers,<br>
&gt;&gt;&gt; Filipe<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt;<br>
&gt;&gt;&gt; On Wed, Aug 5, 2015 at 2:19 PM, Gabriel Guimaraes<br>
&gt;&gt;&gt; &lt;<a href="mailto:gabriellimaguimaraes@gmail.com" target="_blank">gabriellimaguimaraes@gmail.com</a>&gt; wrote:<br>
&gt;&gt;&gt; &gt;<br>
&gt;&gt;&gt; &gt;<br>
&gt;&gt;&gt; &gt; 2015-08-05 13:36 GMT-07:00 Pavel Emelyanov &lt;<a href="mailto:xemul@parallels.com" target="_blank">xemul@parallels.com</a>&gt;:<br>
&gt;&gt;&gt; &gt;&gt;<br>
&gt;&gt;&gt; &gt;&gt; On 08/05/2015 08:51 PM, Gabriel Guimaraes wrote:<br>
&gt;&gt;&gt; &gt;&gt; &gt; Hi Pavel,<br>
&gt;&gt;&gt; &gt;&gt; &gt;<br>
&gt;&gt;&gt; &gt;&gt; &gt; Thanks for the review.<br>
&gt;&gt;&gt; &gt;&gt; &gt;<br>
&gt;&gt;&gt; &gt;&gt; &gt; On Wed, Aug 5, 2015 at 4:00 AM, Pavel Emelyanov &lt;<a href="mailto:xemul@parallels.com" target="_blank">xemul@parallels.com</a><br>
&gt;&gt;&gt; &gt;&gt; &gt; &lt;mailto:<a href="mailto:xemul@parallels.com" target="_blank">xemul@parallels.com</a>&gt;&gt; wrote:<br>
&gt;&gt;&gt; &gt;&gt; &gt;<br>
&gt;&gt;&gt; &gt;&gt; &gt;     Gabriel,<br>
&gt;&gt;&gt; &gt;&gt; &gt;<br>
&gt;&gt;&gt; &gt;&gt; &gt;     Please, find my comments inline.<br>
&gt;&gt;&gt; &gt;&gt; &gt;<br>
&gt;&gt;&gt; &gt;&gt; &gt;     &gt; diff --git a/crtools.c b/crtools.c<br>
&gt;&gt;&gt; &gt;&gt; &gt;     &gt; index 6af6080..521d0ff 100644<br>
&gt;&gt;&gt; &gt;&gt; &gt;     &gt; --- a/crtools.c<br>
&gt;&gt;&gt; &gt;&gt; &gt;     &gt; +++ b/crtools.c<br>
&gt;&gt;&gt; &gt;&gt; &gt;     &gt; @@ -235,6 +235,7 @@ int main(int argc, char *argv[], char<br>
&gt;&gt;&gt; &gt;&gt; &gt; *envp[])<br>
&gt;&gt;&gt; &gt;&gt; &gt;     &gt;               { &quot;enable-fs&quot;,<br>
&gt;&gt;&gt; &gt;&gt; &gt; required_argument,<br>
&gt;&gt;&gt; &gt;&gt; &gt; 0, 1065 },<br>
&gt;&gt;&gt; &gt;&gt; &gt;     &gt;               { &quot;enable-external-sharing&quot;,    no_argument,<br>
&gt;&gt;&gt; &gt;&gt; &gt; 0, 1066 },<br>
&gt;&gt;&gt; &gt;&gt; &gt;     &gt;               { &quot;enable-external-masters&quot;,    no_argument,<br>
&gt;&gt;&gt; &gt;&gt; &gt; 0, 1067 },<br>
&gt;&gt;&gt; &gt;&gt; &gt;     &gt; +             { &quot;overlayfs&quot;,                  no_argument,<br>
&gt;&gt;&gt; &gt;&gt; &gt; 0, 1068 },<br>
&gt;&gt;&gt; &gt;&gt; &gt;<br>
&gt;&gt;&gt; &gt;&gt; &gt;     With AUFS workaround we ended up with auto-detection scheme --<br>
&gt;&gt;&gt; &gt;&gt; &gt; when<br>
&gt;&gt;&gt; &gt;&gt; &gt;     meeting an AUFS mount the opts.aufs is set to true. Can we do the<br>
&gt;&gt;&gt; &gt;&gt; &gt;     same with overlayfs?<br>
&gt;&gt;&gt; &gt;&gt; &gt;<br>
&gt;&gt;&gt; &gt;&gt; &gt;<br>
&gt;&gt;&gt; &gt;&gt; &gt; Technically we could always enable overlayfs by default, since we<br>
&gt;&gt;&gt; &gt;&gt; &gt; only<br>
&gt;&gt;&gt; &gt;&gt; &gt; do something if there<br>
&gt;&gt;&gt; &gt;&gt; &gt; is an overlayfs mounted entry in the mountinfo table. Should I enable<br>
&gt;&gt;&gt; &gt;&gt; &gt; it<br>
&gt;&gt;&gt; &gt;&gt; &gt; always?<br>
&gt;&gt;&gt; &gt;&gt;<br>
&gt;&gt;&gt; &gt;&gt; In the fill_fdlink() there&#39;s fd_parms structure with fs_type field<br>
&gt;&gt;&gt; &gt;&gt; filled<br>
&gt;&gt;&gt; &gt;&gt; from<br>
&gt;&gt;&gt; &gt;&gt; statfs() syscall. If we check for this value being overlayfs magic, we<br>
&gt;&gt;&gt; &gt;&gt; can<br>
&gt;&gt;&gt; &gt;&gt; silently<br>
&gt;&gt;&gt; &gt;&gt; imply the workaround is on and go calling fixup_overlayfs().<br>
&gt;&gt;&gt; &gt;&gt;<br>
&gt;&gt;&gt; &gt; Per man statfs, I don&#39;t think Overlayfs has a magic number. OverlayFS<br>
&gt;&gt;&gt; &gt; just<br>
&gt;&gt;&gt; &gt; overlays two filesystems on top of each other. From statfs&#39; point of<br>
&gt;&gt;&gt; &gt; view, a<br>
&gt;&gt;&gt; &gt; file&#39;s filesystem type is the original one, not OverlayFS.<br>
&gt;&gt;&gt; &gt;<br>
&gt;&gt;&gt; &gt; More information here:<br>
&gt;&gt;&gt; &gt; <a href="https://www.kernel.org/doc/Documentation/filesystems/overlayfs.txt" rel="noreferrer" target="_blank">https://www.kernel.org/doc/Documentation/filesystems/overlayfs.txt</a><br>
&gt;&gt;&gt; &gt;&gt;<br>
&gt;&gt;&gt; &gt;&gt; &gt;     &gt; +static struct mount_info *__lookup_overlayfs(struct mount_info<br>
&gt;&gt;&gt; &gt;&gt; &gt; *list, char *rpath,<br>
&gt;&gt;&gt; &gt;&gt; &gt;     &gt; +                                             unsigned int<br>
&gt;&gt;&gt; &gt;&gt; &gt; st_dev,<br>
&gt;&gt;&gt; &gt;&gt; &gt; unsigned int st_ino,<br>
&gt;&gt;&gt; &gt;&gt; &gt;     &gt; +                                             unsigned int<br>
&gt;&gt;&gt; &gt;&gt; &gt; mnt_id)<br>
&gt;&gt;&gt; &gt;&gt; &gt;     &gt; +{<br>
&gt;&gt;&gt; &gt;&gt; &gt;     &gt; +     /*<br>
&gt;&gt;&gt; &gt;&gt; &gt;     &gt; +      * Goes through all entries in the mountinfo table<br>
&gt;&gt;&gt; &gt;&gt; &gt;     &gt; +      * looking for a mount point that contains the file<br>
&gt;&gt;&gt; &gt;&gt; &gt; specified<br>
&gt;&gt;&gt; &gt;&gt; &gt;     &gt; +      * in rpath. Uses the device number st_dev and the inode<br>
&gt;&gt;&gt; &gt;&gt; &gt; number st_ino<br>
&gt;&gt;&gt; &gt;&gt; &gt;     &gt; +      * to make sure the file is correct.<br>
&gt;&gt;&gt; &gt;&gt; &gt;     &gt; +      */<br>
&gt;&gt;&gt; &gt;&gt; &gt;     &gt; +     struct mount_info *mi_ret = NULL;<br>
&gt;&gt;&gt; &gt;&gt; &gt;     &gt; +     struct mount_info *m;<br>
&gt;&gt;&gt; &gt;&gt; &gt;     &gt; +<br>
&gt;&gt;&gt; &gt;&gt; &gt;     &gt; +     for (m = list; m != NULL; m = m-&gt;next) {<br>
&gt;&gt;&gt; &gt;&gt; &gt;     &gt; +             /* Case 1: If mnt_id is correct, don&#39;t do<br>
&gt;&gt;&gt; &gt;&gt; &gt; anything<br>
&gt;&gt;&gt; &gt;&gt; &gt; */<br>
&gt;&gt;&gt; &gt;&gt; &gt;     &gt; +             if (st_dev == m-&gt;s_dev &amp;&amp; mnt_id == m-&gt;mnt_id)<br>
&gt;&gt;&gt; &gt;&gt; &gt;     &gt; +                     return NULL;<br>
&gt;&gt;&gt; &gt;&gt; &gt;<br>
&gt;&gt;&gt; &gt;&gt; &gt;     Shouldn&#39;t this if () be under the next one, so that everything<br>
&gt;&gt;&gt; &gt;&gt; &gt; that<br>
&gt;&gt;&gt; &gt;&gt; &gt; happens<br>
&gt;&gt;&gt; &gt;&gt; &gt;     here applies to overlayfs only?<br>
&gt;&gt;&gt; &gt;&gt; &gt;<br>
&gt;&gt;&gt; &gt;&gt; &gt;<br>
&gt;&gt;&gt; &gt;&gt; &gt; This if () is basically a check to see if the bug exists. We look for<br>
&gt;&gt;&gt; &gt;&gt; &gt; all instances of the device<br>
&gt;&gt;&gt; &gt;&gt; &gt; st_dev and see if any of them match our mnt_id. If that&#39;s not the<br>
&gt;&gt;&gt; &gt;&gt; &gt; case,<br>
&gt;&gt;&gt; &gt;&gt; &gt; the bug exists and we want<br>
&gt;&gt;&gt; &gt;&gt; &gt; to proceed to try to fix it.<br>
&gt;&gt;&gt; &gt;&gt;<br>
&gt;&gt;&gt; &gt;&gt; OK<br>
&gt;&gt;&gt; &gt;&gt;<br>
&gt;&gt;&gt; &gt;&gt; &gt; I could have left this as a separate for loop to make this more<br>
&gt;&gt;&gt; &gt;&gt; &gt; clear,<br>
&gt;&gt;&gt; &gt;&gt; &gt; but this way we only use<br>
&gt;&gt;&gt; &gt;&gt; &gt; one for loop for both. I believe it&#39;s better if we separate it into<br>
&gt;&gt;&gt; &gt;&gt; &gt; two<br>
&gt;&gt;&gt; &gt;&gt; &gt; for loops since we prevent<br>
&gt;&gt;&gt; &gt;&gt; &gt; some unnecessary stating. I can also move this part to<br>
&gt;&gt;&gt; &gt;&gt; &gt; lookup_overlayfs,<br>
&gt;&gt;&gt; &gt;&gt; &gt; before dealing with<br>
&gt;&gt;&gt; &gt;&gt; &gt; namespaces. What do you think?<br>
&gt;&gt;&gt; &gt;&gt;<br>
&gt;&gt;&gt; &gt;&gt; Yup, makes sense to me.<br>
&gt;&gt;&gt; &gt;&gt;<br>
&gt;&gt;&gt; &gt;<br>
&gt;&gt;<br>
&gt;&gt;<br>
</div></div></blockquote></div><br></div>
</div></div></blockquote></div><br></div>