Hi, I would like access to `va_nlink' information in struct vattr. The purpose is to know when VTEXT node of a running process is "detached" from filesystem (read: the running process isn't the same anymore than the file on disk, maybe due to upgrade).
`va_nlink' is the number of references of the vnode. When it is zero, it means, if I correctly understood, that underling file is dangle. The file has been unlinked. Currently, in order to access to this information from userland, I need to copte with kvm, which is bad (from my perspective). I implemented it for my personal use (https://github.com/semarie/checkrestart), but I would prefer a better approch, and if it is available from base, it would be wonderful. 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'. In order to illustrate the use of the va_nlink information, I also makes a diff for fstat(1): the inode number will be followed by `*' when it is unlinked from disk. For me, this information is highlty desirable as it could permit to easily found processes that would need restart after packages upgrades (rcctl restart ...). 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. Here a concret example with fstat(1): # get the inode of the file sndiod $ ls -i /usr/bin/sndiod 2754462 /usr/bin/sndiod # check the inode of the running sndiod process $ fstat | grep 'sndio.*text' _sndio sndiod 56390 text /usr 2754462 -r-xr-xr-x r 80160 _sndiop sndiod 27240 text /usr 2754462 -r-xr-xr-x r 80160 # recompile sndiod program, and install it: inode 2754462 will be # removed, and a new file installed. $ cd /usr/src/usr.bin/sndiod && make clean && make && doas make install ... # get the new inode $ ls -i /usr/bin/sndiod 2754467 /usr/bin/sndiod # check that the running sndiod process is still the "old" one: # the inode 2754462 is suffixed with `*' $ fstat | grep 'sndio.*text' _sndio sndiod 56390 text /usr 2754462* -r-xr-xr-x r 80160 _sndiop sndiod 27240 text /usr 2754462* -r-xr-xr-x r 80160 # restart sndiod, as the running copy isn't in sync with filesystem $ doas rcctl restart sndiod sndiod(ok) sndiod(ok) # check that now, the running process use the new inode. $ fstat | grep 'sndio.*text' _sndio sndiod 79950 text /usr 2754467 -r-xr-xr-x r 80160 _sndiop sndiod 1725 text /usr 2754467 -r-xr-xr-x r 80160 Does it make any interest ? Thanks. -- Sebastien Marie Index: sys/kern/kern_sysctl.c =================================================================== RCS file: /cvs/src/sys/kern/kern_sysctl.c,v retrieving revision 1.311 diff -u -p -r1.311 kern_sysctl.c --- sys/kern/kern_sysctl.c 21 Sep 2016 14:06:50 -0000 1.311 +++ sys/kern/kern_sysctl.c 24 Sep 2016 11:26:24 -0000 @@ -1057,6 +1057,7 @@ fill_file(struct kinfo_file *kf, struct kf->va_size = va.va_size; kf->va_rdev = va.va_rdev; kf->va_fsid = va.va_fsid & 0xffffffff; + kf->va_nlink = va.va_nlink; } break; Index: sys/sys/sysctl.h =================================================================== RCS file: /cvs/src/sys/sys/sysctl.h,v retrieving revision 1.166 diff -u -p -r1.166 sysctl.h --- 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]; /* socket information */ Index: usr.bin/fstat/fstat.1 =================================================================== RCS file: /cvs/src/usr.bin/fstat/fstat.1,v retrieving revision 1.52 diff -u -p -r1.52 fstat.1 --- usr.bin/fstat/fstat.1 25 Apr 2016 19:18:41 -0000 1.52 +++ usr.bin/fstat/fstat.1 24 Sep 2016 11:26:25 -0000 @@ -146,6 +146,9 @@ flag is specified, this header is presen major/minor number of the device that this file resides in. .It Li INUM The inode number of the file. +It will be followed by an asterisk +.Pq Ql * +if the inode is unlinked from disk. .It Li MODE The mode of the file. If the Index: usr.bin/fstat/fstat.c =================================================================== RCS file: /cvs/src/usr.bin/fstat/fstat.c,v retrieving revision 1.88 diff -u -p -r1.88 fstat.c --- usr.bin/fstat/fstat.c 4 May 2016 19:48:08 -0000 1.88 +++ usr.bin/fstat/fstat.c 24 Sep 2016 11:26:27 -0000 @@ -441,7 +441,9 @@ vtrans(struct kinfo_file *kf) (void)snprintf(mode, sizeof(mode), "%o", kf->va_mode); else strmode(kf->va_mode, mode); - printf(" %8llu %11s", kf->va_fileid, mode); + printf(" %8llu%s %11s", kf->va_fileid, + kf->va_nlink == 0 ? "*" : " ", + mode); rw[0] = '\0'; if (kf->f_flag & FREAD) strlcat(rw, "r", sizeof rw);
