tech-kern archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: procfs files vs symlink
On Wed, 12 Jan 2022, Robert Elz wrote:
| > What causes that EINVAL?
|
|
| I'm not sure (somneone suggested that the file descriptor has been closed
| when ls tries to fstat() it, but I can't confirm this).
That should generate EBADF not EINVAL. Attempting readlink()
on something that is not a symlink, and various other possibilities
like that would be more probable. EINVAL isn't listed as a possible
error return from [f]stat ... not that that guarantees that it cannot
happen, particularly from within emulation code.
That someone is me. But, your're right about this. The EINVAL is caused by
using readlink() on what was a symlink, but, is not anymore because the fd
now points to a regular file.
ktrace ls -l /proc/self/fd
1954 1954 ls CALL open(0x7d9270fdc000,0x600004,3)
1954 1954 ls NAMI "/proc/self/fd"
1954 1954 ls RET open 4
1954 1954 ls CALL fchdir(4)
1954 1954 ls CALL __getdents30(4,0x7d9270fa6000,0x1000)
1954 1954 ls CALL __lstat50(0x7d9270fd12f0,0x7d9270fd12f8)
1954 1954 ls NAMI "0"
1954 1954 ls RET __lstat50 0
1954 1954 ls CALL __lstat50(0x7d9270fd1430,0x7d9270fd1438)
1954 1954 ls NAMI "1"
1954 1954 ls RET __lstat50 0
1954 1954 ls CALL __lstat50(0x7d9270fd1570,0x7d9270fd1578)
1954 1954 ls NAMI "2"
1954 1954 ls RET __lstat50 0
1954 1954 ls CALL __lstat50(0x7d9270fd16b0,0x7d9270fd16b8)
1954 1954 ls NAMI "3"
1954 1954 ls RET __lstat50 0
1954 1954 ls CALL __lstat50(0x7d9270fd17f0,0x7d9270fd17f8)
1954 1954 ls NAMI "4"
Up to this point fd 4 is a symlink which is, presumably, being
cached by ls(1).
1954 1954 ls CALL close(4)
passwd db now opened at 4 which now is a regular file.
1954 1954 ls CALL open(0x7d92705b0006,0x400000,0)
1954 1954 ls NAMI "/etc/pwd.db"
1954 1954 ls RET open 4
Now ls(1) does the listing:
1954 1954 ls GIO fd 1 wrote 44 bytes
"crw--w---- 1 rvp tty 5, 2 Jan 13 04:05 0\n"
1954 1954 ls RET write 44/0x2c
1954 1954 ls CALL write(1,0x7d9270fa2000,0x2c)
1954 1954 ls GIO fd 1 wrote 44 bytes
"crw--w---- 1 rvp tty 5, 2 Jan 13 04:05 1\n"
1954 1954 ls RET write 44/0x2c
1954 1954 ls CALL write(1,0x7d9270fa2000,0x2c)
1954 1954 ls GIO fd 1 wrote 44 bytes
"crw--w---- 1 rvp tty 5, 2 Jan 13 04:05 2\n"
1954 1954 ls CALL readlink(0x7f7fff425a30,0x7f7fff425e40,0x400)
1954 1954 ls NAMI "/proc/self/fd/3"
1954 1954 ls RET readlink 4
1954 1954 ls CALL write(1,0x7d9270fa2000,0x34)
1954 1954 ls GIO fd 1 wrote 52 bytes
"lr-xr-xr-x 1 rvp rvp 240 Jan 13 04:05 3 -> /tmp\n"
The readlink on 4 will fail because it is no longer the symlink it
originally was:
1954 1954 ls CALL readlink(0x7f7fff425a30,0x7f7fff425e40,0x400)
1954 1954 ls NAMI "/proc/self/fd/4"
1954 1954 ls RET readlink -1 errno 22 Invalid argument
Anyway, here's one more patch:
---START PATCH---
--- sys/miscfs/procfs/procfs_vnops.c.orig 2022-01-12 20:57:25.944841288 +0000
+++ sys/miscfs/procfs/procfs_vnops.c 2022-01-12 23:07:44.736070587 +0000
@@ -1410,7 +1410,7 @@
d.d_fileno = PROCFS_FILENO(pfs->pfs_pid, PFSfd, i - 2);
d.d_namlen = snprintf(d.d_name, sizeof(d.d_name),
"%lld", (long long)(i - 2));
- d.d_type = VREG;
+ d.d_type = DT_UNKNOWN; /* convert vtype -> DT_XXX ? */
if ((error = uiomove(&d, UIO_MX, uio)) != 0)
break;
if (cookies)
---END PATCH---
DT_UNKNOWN is not quite right either, but that's better than VREG
which corresponds to DT_FIFO.
-RVP
Home |
Main Index |
Thread Index |
Old Index