On Sat, 24 Sep 2016, Sebastien Marie wrote:
...
> The following diff adds a `va_nlink' member in `struct kinfo_file'. The
> information become available though sysctl(3) via KERN_FILE interface,
> as some others members of `struct vattr'.

The idea seems sound, but the placement of the member in the structure is 
a problem:

> --- sys/sys/sysctl.h  21 Sep 2016 14:06:50 -0000      1.166
> +++ sys/sys/sysctl.h  24 Sep 2016 11:26:25 -0000
> @@ -697,6 +697,7 @@ struct kinfo_file {
>       uint64_t        va_size;        /* UINT64_T: file size in bytes */
>       uint32_t        va_mode;        /* MODE_T: file access mode and type */
>       uint32_t        va_fsid;        /* DEV_T: filesystem device */
> +     uint32_t        va_nlink;       /* NLINK_T: number of references to 
> file */
>       char            f_mntonname[KI_MNAMELEN];

That changes the layout of the structure, changing the ABI.  If instead 
the new member is placed at the end of structure then there's no ABI 
break, as the API permits additions to the end of structure.

Also, libkvm/kvm_file2.c should be updated to match the change to 
kern_sysctl.c, so that the information is returned when debugging kernel 
crash dumps.


> Formally, for the final purpose, the information could be only partial: 
> a library dynamically linked isn't referenced via KERN_FILE interface (I 
> am unsure about the availability of the information). But as proper 
> packages will have their signature changed by any library crank, a 
> package update will make old program to be remplaced by a new one.

Yeah, mmap's hold references to files, but the KERN_FILE API doesn't see 
them.  To get that you would need to walk the maps in the uvmspace and 
pick out the non-anonymous mappings, skipping the base executable (which 
_is_ already returned by KERN_FILE).  Doing that without races in the 
kernel would be tricky, as copyout() can sleep if there's a page fault.  
Could you deadlock the kernel by asking for information about your own 
mappings, with sysctl() writing to a mapping which would need to be 
faulted in?

Perhaps better to not hold a lock over copyout() but instead just track 
the vaddr range that was being reported, and then restart the tree walk 
from there.  That guarantees progress with no locks held.


Philip Guenther

Reply via email to