Re: fcntl F_KINFO for

From: Konstantin Belousov <kostikbel_at_gmail.com>
Date: Sat, 14 May 2022 19:53:06 UTC
On Sat, May 14, 2022 at 09:45:26PM +0200, Paul Floyd wrote:
> Hi
> 
> I'm working on updating Valgrind for FreeBSD 13.1.
> 
> I've been trying to rewrite some of the code (used in tracking file
> descriptors, --track-fds=yes) to use fcntl and F_KINFO. The old code was IMO
> ugly, using KERN_PROC_FILEDESC to get info on all open files and then do a
> linear search for the fd.
> 
> The new code is a lot shorter, but it doesn't quite work correctly. The
> Valgrind regression test system redirects stdout and stderr, which it then
> filters and compares to reference files. fcntl / F_KINFO doesn't seem to
> work correctly with fd 1 (or at least, that seems to be the problem the most
> often).
> 
> Here is a small reproducer
> 
> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include
> <fcntl.h> #include <sys/mman.h> #include <sys/types.h> #include <sys/user.h>
> int main(void) { struct kinfo_file kf; kf.kf_structsize = KINFO_FILE_SIZE;
> if (0 == fcntl( 1, F_KINFO, &kf )) { printf("fcntl succeeded %s\n",
> kf.kf_path); } else { printf("fcntl failed\n"); } }
> 
> Compiled with
> 
> clang -g -o fcntl fcntl.c
> 
> Then run it.
> 
> For the first run
> 
> $ ./fcntl > foo $ cat foo fcntl succeeded
> 
> There's an empty string for kf_path there.
> 
> Now that foo exists
> 
> $ ./fcntl > foo $ cat foo fcntl succeeded /usr/home/paulf/foo
> 
> Am I doing something wrong here or is this a bug / misfeature in the
> implementation of gcntl / K_INFO?

When open(2) creates a new file, the vnode name is not entered into
the name cache.  I believe this is done to smoother the case like
untarring large set of files, which would replace existing cached
entries with probably not too useful new entries.

F_KINFO uses name cache to reconstruct the last element of the path,
on most real file systems like UFS.  If this last element is not cached,
F_KINFO is unable to return the path.