Page MenuHomeFreeBSD

mount: add vnode usage per file system with mount -v.
ClosedPublic

Authored by ambrisko on Jun 8 2022, 5:16 PM.

Details

Summary

This avoids the need to drop into the ddb to figure out vnode
usage per file system. It helps to see if they are or are not
being freed.

Test Plan

Tested with and without kernel change with kernel change. With:

client% mount -v
 192.168.35.1:/data/home/ambrisko/netboot on / (nfs, fsid 01ff003a3a000000, vnodes: count 553 active 72)
devfs on /dev (devfs, fsid 00ff007171000000, vnodes: count 27 active 16)
procfs on /proc (procfs, local, fsid 02ff000202000000, vnodes: count 2 active 1)
linprocfs on /compat/linux/proc (linprocfs, local, fsid 03ff00b5b5000000, vnodes: count 2 active 1)
linsysfs on /compat/linux/sys (linsysfs, local, fsid 04ff008a8a000000, vnodes: count 2 active 1)
fdescfs on /dev/fd (fdescfs, fsid 05ff005959000000, vnodes: count 3 active 2)
tmpfs on /tmp (tmpfs, local, fsid 06ff008787000000, vnodes: count 6 active 2)
tmpfs on /var/tmp (tmpfs, local, fsid 07ff008787000000, vnodes: count 2 active 1)
tmpfs on /var/run (tmpfs, local, fsid 08ff008787000000, vnodes: count 8 active 5)
devfs on /compat/linux/dev (devfs, fsid 09ff007171000000, vnodes: count 4 active 4)
fdescfs on /compat/linux/dev/fd (fdescfs, fsid 0aff005959000000, vnodes: count 2 active 2)
tmpfs on /compat/linux/dev/shm (tmpfs, local, fsid 0bff008787000000, vnodes: count 2 active 1)
192.168.31.1:/data on /data (nfs, fsid 0cff003a3a000000, vnodes: count 2 active 2)
192.168.35.1:/data/home/ambrisko/netboot/usr/local on /usr/local (nfs, fsid 0dff003a3a000000, vnodes: count 73 active 2)
192.168.35.1:/data/home/ambrisko/netboot/var on /var (nfs, fsid 0eff003a3a000000, vnodes: count 82 active 20)

Without:

% ./mount -v
192.168.97.254:/data/home/ambrisko/netboot on / (nfs)
devfs on /dev (devfs)
procfs on /proc (procfs, local)
linprocfs on /compat/linux/proc (linprocfs, local)
linsysfs on /compat/linux/sys (linsysfs, local)
fdescfs on /dev/fd (fdescfs)
tmpfs on /tmp (tmpfs, local)
tmpfs on /var/tmp (tmpfs, local)
tmpfs on /var/run (tmpfs, local)
tmpfs on /var/db/pkg (tmpfs, local)

%
On different machines but with the same binary.

Diff Detail

Repository
rG FreeBSD src repository
Lint
Automatic diff as part of commit; lint not applicable.
Unit
Automatic diff as part of commit; unit tests not applicable.

Event Timeline

Tweak comment of new fields.

ambrisko added reviewers: netchild, kib.
sbin/mount/mount.c
696

Is this line' indentation too large?

sys/sys/mount.h
94

Why do you think that this number is interesting to user?

94–96

I am unsure about 32bit counter there, but do not have sufficient arguments right now. 4G vnodes should be enough.

ambrisko added inline comments.
sys/sys/mount.h
94

I'm not sure how useful it is. I figured we could fit them both in the 64 bit reserved slot.

sys/sys/mount.h
94–96

May be, export only vnodelistsize, in 64bit counter?

I do not object against lazy size, but it is some minor implementation detail. Basically it is list of vnodes where e.g. inactivation or atime processing was deferred due to not suitable context.

sys/sys/mount.h
94–96

In fact, I think another counter would be (much) more useful, namely the active vnode count. It roughly is the count of vnodes which back open files, and also it is the counter which prevents non-forced unmounts. Giving this info to user is IMO indeed valuable.

You would need to calculate it, code should be like this:

count = 0;
MNT_ILOCK(mp);
TAILQ_FOREACH(vp, &mp->mnt_vnodelist, v_nmntvnodes) {
   if (vrefcount(vp) > 0) /* racy but does not matter */
      count++;
}
MNT_IUNLOCK(mp);
sys/sys/mount.h
94–96

I couldn't find vrefcount(), but it the ddb hook I saw:

TAILQ_FOREACH(vp, &mp->mnt_nvnodelist, v_nmntvnodes) {
        if (vp->v_type != VMARKER && vp->v_holdcnt > 0) {
                vn_printf(vp, "vnode ");
                if (db_pager_quit)
                        break;
        }
}

so I tweaked your code snippet to:

count = 0;
MNT_ILOCK(mp);
TAILQ_FOREACH(vp, &mp->mnt_nvnodelist, v_nmntvnodes) {
        //if (vrefcount(vp) > 0) /* racy but does not matter */
        /* racy but does not matter */
        if (vp->v_type != VMARKER && vp->v_holdcnt > 0)
                count++;
}
MNT_IUNLOCK(mp);
sbp->f_avnodecount = count;

Then output like this (without the mount update from lazy to active:
192.168.35.1:/data/home/ambrisko/netboot on / (nfs, fsid 01ff003a3a000000, vnodes: count 547 lazy 531)
devfs on /dev (devfs, fsid 00ff007171000000, vnodes: count 27 lazy 16)
procfs on /proc (procfs, local, fsid 02ff000202000000, vnodes: count 2 lazy 1)
linprocfs on /compat/linux/proc (linprocfs, local, fsid 03ff00b5b5000000, vnodes: count 2 lazy 1)
linsysfs on /compat/linux/sys (linsysfs, local, fsid 04ff008a8a000000, vnodes: count 2 lazy 1)
fdescfs on /dev/fd (fdescfs, fsid 05ff005959000000, vnodes: count 3 lazy 2)
tmpfs on /tmp (tmpfs, local, fsid 06ff008787000000, vnodes: count 6 lazy 2)
tmpfs on /var/tmp (tmpfs, local, fsid 07ff008787000000, vnodes: count 2 lazy 1)
tmpfs on /var/run (tmpfs, local, fsid 08ff008787000000, vnodes: count 8 lazy 5)
devfs on /compat/linux/dev (devfs, fsid 09ff007171000000, vnodes: count 4 lazy 4)
fdescfs on /compat/linux/dev/fd (fdescfs, fsid 0aff005959000000, vnodes: count 2 lazy 2)
tmpfs on /compat/linux/dev/shm (tmpfs, local, fsid 0bff008787000000, vnodes: count 2 lazy 1)
192.168.31.1:/data on /data (nfs, fsid 0cff003a3a000000, vnodes: count 2 lazy 2)
192.168.35.1:/data/home/ambrisko/netboot/usr/local on /usr/local (nfs, fsid 0dff003a3a000000, vnodes: count 73 lazy 72)
192.168.35.1:/data/home/ambrisko/netboot/var on /var (nfs, fsid 0eff003a3a000000, vnodes: count 82 lazy 49)

sys/sys/mount.h
94–96

Sorry, it is vrefcnt(), I wrote the snippet from memory. See sys/vnode.h, line 1052.
If you still want to use the vnode field directly, it is v_usecount > 0 that idenitifies active vnodes, not v_holdcnt. The check for VMARKER is not strongly necessary.

Also please replace 'lazy' name with 'active' in the userspace printf.

Changed lazy to active per kib@

This revision is now accepted and ready to land.Jun 10 2022, 4:34 PM
ambrisko added inline comments.
sys/sys/mount.h
94–96

Updated the review with the new code. FYI, I was running the old mount binary with a POC of the kernel change. I have updated mount to reflect the change. Thanks.

This revision was automatically updated to reflect the committed changes.
ambrisko marked an inline comment as done.