7

How do I discover, for a given top-level directory, which “real” filesystems are mounted there, and from which devices (may include UUID or LABEL, but must use /dev/something for LVM)?

Background is automated fstab(5) generation from a script that would run after debootstrap; the host OS is GNU/Linux (I think not everything I use in subroutines is GNU/kFreeBSD‑ or GNU/Hurd-safe).

The closest thing I’ve found so far is findmnt -l --real but this still shows bind mounts, which aren’t “real enough” for my use case, I need block device-backed mountpoints. (This may include loop mounts.)

2
  • a bind mount is indistinguishable from the original even if it accesses only part of that file system. this is done as a way to indicate the path in a way that keeps kernel code simple and secure, as well as sharing as much memory data, like cache, as possible. you can unmount the original and the bind mount is still as real. both are always equally real. Commented May 18, 2022 at 0:45
  • @Skaperen this is wrong (see the first answer and my first comment on it). Commented May 18, 2022 at 18:33

2 Answers 2

8

From the perspective of the Linux kernel, there is no difference between bind mounts and "regular" mounts. They are conceptually closer to hard links than symbolic links.

Nevertheless you can narrow it down somewhat with e.g.

findmnt -lv --real --output "FSROOT,SOURCE,TARGET,FSTYPE,OPTIONS" | grep "^/\s" 

This filters out all mounts which have a FSROOT (path in the mounted filesystem that is linked to the mountpoint) other than /.

Bind mounts that remount the whole filesystem like

mount /dev/sda /a mount --bind /a /b 

are harder to detect. You need to further filter the list by comparing the SOURCE or MAJ:MIN columns and remove duplicates that way.

There are still some edge cases (e.g. bind mounts to subdirectories/files starting with a space character are falsely accepted by the regex and Btrfs subvolume mounts look like bind mounts so they are removed from the list) but this should give you a starting point.

5
  • perhaps a better name for bind mounts is shared mounts. Commented May 18, 2022 at 0:47
  • Hmm, but the SOURCE column already has [sourcepath] for bindmounts (other than the whole-filesystem ones), so detecting them is probably possible (see if the path exists, filter out if not). I guess I’ll have to write that part myself, then. And hope that this method doesn’t filter out too much… Commented May 18, 2022 at 18:32
  • 1
    @mirabilos findmnt by default doesn't display the FSROOT column I used in my answer and instead puts the path in brackets (if not /) into the SOURCE column. It often signifies a bind mount but may also be a Btrfs subvolume mount, so you always need to handle some edge cases. Commented May 19, 2022 at 14:16
  • Yeah, I figure so now, too. Parsing findmnt(8) output is a PITA (it encodes things in hex but fstab(5) only supports octal; it doesn’t list things in a way you can read with shell; etc.) but I guess I’ll list sufficient columns (notably FSROOT but also {,PART}{UUID,LABEL} to use for nōn-LVM sources) and deal with bind mounts somehow. No idea about btrfs. It’s only meant to pre-fill fstab anyway, so the user would possibly still need to edit it (e.g. to add the swap device). Commented May 19, 2022 at 20:37
  • FWIW, as a follow-up, with this I managed this script which is a good 99% solution. Commented Dec 1, 2024 at 19:40
0

This is what I would do (if I understand what all you are asking)

  1. alias lsblk2='lsblk -o size,fstype,model,name,serial,uuid'
  2. lsblk2
  3. first observe all the block devices that linux sees, and with seeing FSTYPE you'll be able to judge what is where and what you want
  4. I would recommend not mounting by device-name such as /dev/sda because as disks come and go then sda can become a different disk, so it is better to mount by uuid.
  5. view /etc/mtab to see what is currently mounted, and view /etc/fstab for what would be mounted after booting.
  6. based on the display from lsblk2 add or adjust /etc/fstab accordingly

three sample /etc/fstab entries:

UUID=800e924a-a869-4152-9503-9d9cfecbd16e / xfs defaults 0 0 UUID=4f3da85a-71a9-4f6e-bc5f-dfd23a880b08 /boot xfs defaults 0 0 /dev/disk/by-uuid/e0791b9e-b620-4274-9857-78389b10f5a5 /data auto nosuid,nodev,nofail,x-gvfs-show 0 0 

simply type mount to see all currently mounted filesystems

type just findmnt, on rhel 7.9 this is what I get:

TARGET SOURCE FSTYPE OPTIONS / /dev/sda3 xfs rw,relatime,seclabel,attr2,inode64,logbsize=64k,sunit=128,swidth= ├─/sys sysfs sysfs rw,nosuid,nodev,noexec,relatime,seclabel │ ├─/sys/kernel/security securityfs securityfs rw,nosuid,nodev,noexec,relatime │ ├─/sys/fs/cgroup tmpfs tmpfs ro,nosuid,nodev,noexec,seclabel,mode=755 │ │ ├─/sys/fs/cgroup/systemd cgroup cgroup rw,nosuid,nodev,noexec,relatime,seclabel,xattr,release_agent=/usr │ │ ├─/sys/fs/cgroup/net_cls,net_prio cgroup cgroup rw,nosuid,nodev,noexec,relatime,seclabel,net_prio,net_cls │ │ ├─/sys/fs/cgroup/cpu,cpuacct cgroup cgroup rw,nosuid,nodev,noexec,relatime,seclabel,cpuacct,cpu │ │ ├─/sys/fs/cgroup/freezer cgroup cgroup rw,nosuid,nodev,noexec,relatime,seclabel,freezer │ │ ├─/sys/fs/cgroup/pids cgroup cgroup rw,nosuid,nodev,noexec,relatime,seclabel,pids │ │ ├─/sys/fs/cgroup/devices cgroup cgroup rw,nosuid,nodev,noexec,relatime,seclabel,devices │ │ ├─/sys/fs/cgroup/blkio cgroup cgroup rw,nosuid,nodev,noexec,relatime,seclabel,blkio │ │ ├─/sys/fs/cgroup/perf_event cgroup cgroup rw,nosuid,nodev,noexec,relatime,seclabel,perf_event │ │ ├─/sys/fs/cgroup/hugetlb cgroup cgroup rw,nosuid,nodev,noexec,relatime,seclabel,hugetlb │ │ ├─/sys/fs/cgroup/memory cgroup cgroup rw,nosuid,nodev,noexec,relatime,seclabel,memory │ │ └─/sys/fs/cgroup/cpuset cgroup cgroup rw,nosuid,nodev,noexec,relatime,seclabel,cpuset │ ├─/sys/fs/pstore pstore pstore rw,nosuid,nodev,noexec,relatime │ ├─/sys/firmware/efi/efivars efivarfs efivarfs rw,nosuid,nodev,noexec,relatime │ ├─/sys/kernel/config configfs configfs rw,relatime │ ├─/sys/fs/selinux selinuxfs selinuxfs rw,relatime │ ├─/sys/kernel/debug debugfs debugfs rw,relatime │ └─/sys/fs/fuse/connections fusectl fusectl rw,relatime ├─/proc proc proc rw,nosuid,nodev,noexec,relatime │ └─/proc/sys/fs/binfmt_misc systemd-1 autofs rw,relatime,fd=35,pgrp=1,timeout=0,minproto=5,maxproto=5,direct,p │ └─/proc/sys/fs/binfmt_misc binfmt_misc binfmt_misc rw,relatime ├─/dev devtmpfs devtmpfs rw,nosuid,seclabel,size=395484100k,nr_inodes=98871025,mode=755 │ ├─/dev/shm tmpfs tmpfs rw,nosuid,nodev,seclabel │ ├─/dev/pts devpts devpts rw,nosuid,noexec,relatime,seclabel,gid=5,mode=620,ptmxmode=000 │ ├─/dev/hugepages hugetlbfs hugetlbfs rw,relatime,seclabel │ └─/dev/mqueue mqueue mqueue rw,relatime,seclabel ├─/run tmpfs tmpfs rw,nosuid,nodev,seclabel,mode=755 │ ├─/run/user/3584810 tmpfs tmpfs rw,nosuid,nodev,relatime,seclabel,size=79100268k,mode=700,uid=358 │ │ └─/run/user/3584810/gvfs gvfsd-fuse fuse.gvfsd-f rw,nosuid,nodev,relatime,user_id=3584810,group_id=100 │ ├─/run/user/2001 tmpfs tmpfs rw,nosuid,nodev,relatime,seclabel,size=79100268k,mode=700,uid=200 │ └─/run/user/329918 tmpfs tmpfs rw,nosuid,nodev,relatime,seclabel,size=79100268k,mode=700,uid=329 ├─/tmp tmpfs tmpfs rw,seclabel ├─/boot /dev/sda2 xfs rw,relatime,seclabel,attr2,inode64,logbsize=64k,sunit=128,swidth= │ └─/boot/efi /dev/sda1 vfat rw,relatime,fmask=0077,dmask=0077,codepage=437,iocharset=ascii,sh ├─/data /dev/sdb1 xfs rw,nosuid,nodev,relatime,seclabel,attr2,inode64,logbsize=64k,suni ├─/var/lib/nfs/rpc_pipefs sunrpc rpc_pipefs rw,relatime ├─/bkup bkup:/bkup nfs4 rw,nosuid,noexec,relatime,vers=4.1,rsize=1048576,wsize=1048576,na └─/ramdisk tmpfs tmpfs rw,relatime,seclabel,size=775946240k 

with all this in hand not sure what else could be needed to solve any kind of mount issue.

1
  • I was aiming at an automated solution. I know how to do these by hand… Commented May 19, 2022 at 18:55

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.