Bug 24014 - no results from readdir on host-mapped filesystem in Qemu with old host kernel
Summary: no results from readdir on host-mapped filesystem in Qemu with old host kernel
Status: RESOLVED DUPLICATE of bug 23960
Alias: None
Product: glibc
Classification: Unclassified
Component: libc (show other bugs)
Version: 2.28
: P2 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2018-12-20 15:50 UTC by Thomas De Schampheleire
Modified: 2018-12-27 12:01 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Last reconfirmed:
fweimer: security-


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Thomas De Schampheleire 2018-12-20 15:50:39 UTC
I am seeing a readdir-related problem inside qemu-system-i386, when accessing a
'9p' filesystem which is mapped to a host directory. The readdir call does not return any directory entries, not even '.' or '..'.
When accessing a local filesystem like /tmp, readdir does return the expected entries.

The problem is seen when running Qemu on CentOS 7 with kernel 3.10, and not seen when running the same Qemu version 2.11.0 on Gentoo with kernel 4.14.

The target toolchain used to build the test program running inside Qemu is
consisting of gcc 7.3.0, glibc 2.28, binutils 2.31.1.

Test program takes a directory path as argument and prints out the first three
entries received from readdir. In the bad case, this prints nothing.


#include <dirent.h>
#include <stdio.h>

void readonce(DIR *dirp)
{
    struct dirent *d;
    d = readdir(dirp);
    if (d == NULL) {
        printf("no more entries\n");
        return;
    }

    printf("d_name: %s\n", d->d_name);
}

int main(int argc, char *argv[])
{
    DIR *dirp = opendir(argv[1]);
    for (int i = 0; i < 3 ; i++) {
        readonce(dirp);
    }
}


Output from 'strace -v' on the bad case (accessing the 9p filesystem):

openat(AT_FDCWD, "/mnt/nand-dbase/foo/", O_RDONLY|O_NONBLOCK|O_LARGEFILE|O_DIRECTORY|O_CLOEXEC) = 3
fstat64(3, {st_dev=makedev(0, 19), st_ino=361311, st_mode=S_IFDIR|0755, st_nlink=2, st_uid=10570, st_gid=3610, st_blksize=4096, st_blocks=8, st_size=4096, st_atime=1545319664 /* 2018-12-20T15:27:44.400824994+0000 */, st_atime_nsec=400824994, st_mtime=1545319674 /* 2018-12-20T15:27:54.205814105+0000 */, st_mtime_nsec=205814105, st_ctime=1545319674 /* 2018-12-20T15:27:54.205814105+0000 */, st_ctime_nsec=205814105}) = 0
brk(NULL)                               = 0x9da0000
brk(0x9dc1000)                          = 0x9dc1000
brk(0x9dc2000)                          = 0x9dc2000
getdents64(3, [{d_ino=361275, d_off=1532808351538279948, d_reclen=24, d_type=DT_DIR, d_name=".."}, {d_ino=358605, d_off=8467452789161523084, d_reclen=24, d_type=DT_REG, d_name="bar"}, {d_ino=361311, d_off=9223372036854775807, d_reclen=24, d_type=DT_DIR, d_name="."}], 32768) = 72
fstat64(1, {st_dev=makedev(0, 6), st_ino=4568, st_mode=S_IFCHR|0600, st_nlink=1, st_uid=0, st_gid=0, st_blksize=4096, st_blocks=0, st_rdev=makedev(4, 65), st_atime=1545319680 /* 2018-12-20T15:28:00.769282559+0000 */, st_atime_nsec=769282559, st_mtime=1545319680 /* 2018-12-20T15:28:00.769282559+0000 */, st_mtime_nsec=769282559, st_ctime=1545313074 /* 2018-12-20T13:37:54.834207421+0000 */, st_ctime_nsec=834207421}) = 0
ioctl(1, TCGETS, {c_iflags=0x1500, c_oflags=0x5, c_cflags=0xcbd, c_lflags=0xa3b, c_line=0, c_cc="\x03\x1c\x7f\x15\x04\x00\x01\x00\x11\x13\x1a\x0a\x12\x0f\x17\x16\x00\x00\x00"}) = 0
write(1, "no more entries\n", 16no more entries
)       = 16
getdents64(3, [], 32768)                = 0
write(1, "no more entries\n", 16no more entries
)       = 16
getdents64(3, [], 32768)                = 0
write(1, "no more entries\n", 16no more entries
)       = 16


Output on the same system but a local filesystem (/tmp):

openat(AT_FDCWD, "/tmp/foo", O_RDONLY|O_NONBLOCK|O_LARGEFILE|O_DIRECTORY|O_CLOEXEC) = 3
fstat64(3, {st_dev=makedev(0, 15), st_ino=15109, st_mode=S_IFDIR|0755, st_nlink=2, st_uid=0, st_gid=0, st_blksize=4096, st_blocks=0, st_size=60, st_atime=1545320147 /* 2018-12-20T15:35:47.893535644+0000 */, st_atime_nsec=893535644, st_mtime=1545320150 /* 2018-12-20T15:35:50.597535644+0000 */, st_mtime_nsec=597535644, st_ctime=1545320150 /* 2018-12-20T15:35:50.597535644+0000 */, st_ctime_nsec=597535644}) = 0
brk(NULL)                               = 0x9f11000
brk(0x9f32000)                          = 0x9f32000
brk(0x9f33000)                          = 0x9f33000
getdents64(3, [{d_ino=15109, d_off=1, d_reclen=24, d_type=DT_DIR, d_name="."}, {d_ino=4856, d_off=2, d_reclen=24, d_type=DT_DIR, d_name=".."}, {d_ino=15110, d_off=3, d_reclen=24, d_type=DT_REG, d_name="bar"}], 32768) = 72
fstat64(1, {st_dev=makedev(0, 6), st_ino=4568, st_mode=S_IFCHR|0600, st_nlink=1, st_uid=0, st_gid=0, st_blksize=4096, st_blocks=0, st_rdev=makedev(4, 65), st_atime=1545320152 /* 2018-12-20T15:35:52.769282559+0000 */, st_atime_nsec=769282559, st_mtime=1545320152 /* 2018-12-20T15:35:52.769282559+0000 */, st_mtime_nsec=769282559, st_ctime=1545313074 /* 2018-12-20T13:37:54.834207421+0000 */, st_ctime_nsec=834207421}) = 0
ioctl(1, TCGETS, {c_iflags=0x1500, c_oflags=0x5, c_cflags=0xcbd, c_lflags=0xa3b, c_line=0, c_cc="\x03\x1c\x7f\x15\x04\x00\x01\x00\x11\x13\x1a\x0a\x12\x0f\x17\x16\x00\x00\x00"}) = 0
write(1, "d_name: .\n", 10d_name: .
)             = 10
write(1, "d_name: ..\n", 11d_name: ..
)            = 11
write(1, "d_name: bar\n", 12d_name: bar
)           = 12


The bad case shows very large d_off values in getdents64, and repeated calls to
this function, while in the good case there is just one call with small d_off
values.

Could be related to #23960 and/or #23497.
Comment 1 Florian Weimer 2018-12-20 16:01:51 UTC
What's the file system on the host that is exported using 9p?  Is it ext4?

Can you try this with XFS instead?  Thanks.
Comment 2 Thomas De Schampheleire 2018-12-21 18:58:31 UTC
(In reply to Florian Weimer from comment #1)
> What's the file system on the host that is exported using 9p?  Is it ext4?
> 
> Can you try this with XFS instead?  Thanks.

I think it is indeed ext4, but the machine is down now for end-of-year maintenance. I will be able to verify it next week.
There is no existing XFS filesystem on the machine, but I will try creating an XFS filesystem in a regular file via loop mount. Would it be sufficient for your question?
Comment 3 Thomas De Schampheleire 2018-12-23 20:21:16 UTC
(In reply to Thomas De Schampheleire from comment #2)
> (In reply to Florian Weimer from comment #1)
> > What's the file system on the host that is exported using 9p?  Is it ext4?
> > 
> > Can you try this with XFS instead?  Thanks.
> 
> I think it is indeed ext4, but the machine is down now for end-of-year
> maintenance. I will be able to verify it next week.
> There is no existing XFS filesystem on the machine, but I will try creating
> an XFS filesystem in a regular file via loop mount. Would it be sufficient
> for your question?

I confirm that the underlying filesystem of the problematic 9p mount is ext4.
If I change the underlying filesystem to be xfs (via a loop mount on a file), there is no problem using the test program.
Comment 4 Adhemerval Zanella 2018-12-27 12:01:36 UTC
(In reply to Thomas De Schampheleire from comment #3)
> (In reply to Thomas De Schampheleire from comment #2)
> > (In reply to Florian Weimer from comment #1)
> > > What's the file system on the host that is exported using 9p?  Is it ext4?
> > > 
> > > Can you try this with XFS instead?  Thanks.
> > 
> > I think it is indeed ext4, but the machine is down now for end-of-year
> > maintenance. I will be able to verify it next week.
> > There is no existing XFS filesystem on the machine, but I will try creating
> > an XFS filesystem in a regular file via loop mount. Would it be sufficient
> > for your question?
> 
> I confirm that the underlying filesystem of the problematic 9p mount is ext4.
> If I change the underlying filesystem to be xfs (via a loop mount on a
> file), there is no problem using the test program.

The seems to be exactly BZ#23960, I will mark is as duplicated.

*** This bug has been marked as a duplicate of bug 23960 ***