ZFS How to list the open files on a zfs filesystem.

Are you running lsof as root? There are a few sysctls that prevent "a process from seeing other processes or groups" and that can affect what a tool can do.
Running lsof as root I see a bunch of "unknown file system type: zfs" so perhaps lsof does not understand ZFS. It's likely a port, so perhaps a quick message to the maintainer?
 
lsof is a port, right, and if it really doesn't support ZFS (I wonder why listing opened files should somehow depend on the underlying filesystem? Shouldn't the VFS be enough?), this is probably missing upstream, so little the maintainer can do about that.

Why not just use fstat(1)? It's part of base.
 
I'm using procstat to list regular files opened by process or user.

The process should be specified by PID:
Code:
# procstat -f PID | egrep ' T V | v r '
  PID COMM                FD T V FLAGS    REF  OFFSET PRO NAME
32326 dd                text v r r-------   -       - -   /bin/dd
32326 dd                   4 v r rw------   2 1975517184 -   /pool/random.dd

The user should be specified by UID or username:
Code:
# procstat -f `ps -o pid= -U UID` | egrep ' T V | v r '
  PID COMM                FD T V FLAGS    REF  OFFSET PRO NAME
6217 sshd              text v r r-------   -       - -   /usr/sbin/sshd
6310 zsh               text v r r-------   -       - -   /usr/local/bin/zsh
6310 zsh                 12 v r r-------   1       0 -   /usr/local/share/zsh/5.8/functions/Completion.zwc
6310 zsh                 13 v r r-------   1       0 -   /usr/local/share/zsh/5.8/functions/Zle.zwc
6310 zsh                 14 v r r-------   1       0 -   /usr/local/share/zsh/5.8/functions/Completion/Base.zwc

The following flags may be displayed: r for read, w for write, a for append, s for async, f for fsync, n for non-blocking, d for direct I/O and l for lock held.

You can set the commands as shell aliases to make life easier.
 
Last edited:
… perhaps lsof does not understand ZFS …

True, for 13.0-RELEASE and 14.0-CURRENT.

FreeBSD bug 253553 – sysutils/lsof: no zfs support on 13

With 14.0-CURRENT, for example:

Code:
# gpart show /dev/da2
gpart: No such geom: /dev/da2.
# lsblk da2
DEVICE         MAJ:MIN SIZE TYPE                              LABEL MOUNT
da2              0:154  14G -                                     - -
# zpool import Transcend ; zpool status Transcend && zfs load-key Transcend/VirtualBox && zfs mount Transcend/VirtualBox ; mount | grep Transcend
  pool: Transcend
state: ONLINE
  scan: scrub repaired 0B in 01:26:19 with 0 errors on Mon May 31 22:14:58 2021
config:

        NAME                 STATE     READ WRITE CKSUM
        Transcend            ONLINE       0     0     0
          gpt/FreeBSD%20ZFS  ONLINE       0     0     0
        cache
          da2                ONLINE       0     0     0

errors: No known data errors
Enter passphrase for 'Transcend/VirtualBox':
Transcend on /Volumes/t500 (zfs, local, nfsv4acls)
Transcend/VirtualBox on /Volumes/t500/VirtualBox (zfs, local, nfsv4acls)
# lsof /Volumes/t500/VirtualBox
lsof: WARNING: device cache mismatch: /dev/da1p1
lsof: WARNING: no ZFS support has been defined.
      See 00FAQ for more information.
lsof: WARNING: /root/.lsof_mowa219-gjp4-8570p was updated.
# lsof /Volumes/t500/VirtualBox
lsof: WARNING: no ZFS support has been defined.
      See 00FAQ for more information.
# zpool export Transcend
cannot unmount '/Volumes/t500/VirtualBox': pool or dataset is busy
#
 
I'm using procstat to list regular files opened by process or user. …

Thanks, things become problematic when a person can't guess which user or process to specify.

For myself, I learnt to begin by killing gvfsd-trash whenever a pool can not be exported. YMMV.

FreeBSD bug 254024 – devel/gvfs: gvfsd-trash latches to zfs volumes includes a recommendation to workaround with force:

umount -f

– however (comment 14) I dislike applying force when it's not known which files are open; and I don't get a list of open files before attempting to unmount.
 
Thanks, how would I adapt that for csh?

Code:
root@mowa219-gjp4-8570p:~ # ps ax -o pid= | xargs procstat -f 2 > /dev/null
procstat: sysctl(kern.proc): No such process
procstat: procstat_getprocs()
root@mowa219-gjp4-8570p:~ # sh
# ps ax -o pid=|xargs procstat -f 2>/dev/null | grep t500
# zpool export Transcend
# exit
root@mowa219-gjp4-8570p:~ # echo $SHELL
/bin/csh
root@mowa219-gjp4-8570p:~ #
 
Too obvious :) thanks again. Still, I'm curious about why the first syntax doesn't work in csh …
you cant easily redirect (only) stderr in csh or at least i dont know how
if you are not bothered by the error (procstat complains of bad pids (one of them is our (by then dead)ps process) then remove 2>/dev/null
 
Back
Top