Hello.
I need to list a directory recursively but I want to skip subdirs that were already mounted.
There are 2 cases:
a) a filesystem was mounted twice, like in this example:
- "/dev/sda2" was mounted on "/mnt/mnt_point1"
- "/dev/sda2" was mounted on "/mnt/mnt_point2"
I want to list "/mnt" but descend only in "/mnt/mnt_point1"
b) part of the file hierarchy was remounted somewhere else, with "mount --bind":
- "mount --bind /home/user/tmp/test /home/user/tmp/mounted_test"
I want to list "/home/user/tmp" but descend only in "test"
"statfs" and "statvfs" don't offer any information to discern if a dir was mounted twice.
One solution would be to read "/etc/mtab" (as "find" command does it) and perform some checks, but I think that this is pretty expensive (one has to read /etc/mtab every time one encounters a dir; if this file is read only when program starts, a mount could occur in between reads, so that the program will be inaccurate).
Another solution would be to filter kernel events (via libudev or Netlink) and do this reading of /etc/mtab only when a MOUNT event was issued.
Do you have any other suggestions? Thanks in advance.
Was meant to suggest that not all Unixs have mtab. You can't depend on it if it doesn't always exist. And even when Linux compatibility is switch on (if it exists) it may not go in /etc.
Note: like Linux, FreeBSD uses the file /etc/fstab to determine how to mount filesystems; however, it does not use the file /etc/mtab. (If you've installed Linux compatibility, use more /usr/compat/linux/proc/mtab instead.) The commands mount and df list the currently mounted filesystems.
Thanks for the replies.
I know that I'm not supposed to rely on /etc/mtab:
"The filenames given above should never be used directly. The portable way to handle these file is to use the macro _PATH_FSTAB, defined in fstab.h, or _PATH_MNTTAB, defined in mntent.h and paths.h, for fstab; and the macro _PATH_MOUNTED, also defined in mntent.h and paths.h, for mtab. There are also two alternate macro names FSTAB, MNTTAB, and MOUNTED defined but these names are deprecated and kept only for backward compatibility. The names _PATH_MNTTAB and _PATH_MOUNTED should always be used."
this is what "find" does, i.e reading this file using the defined macro.
It's ok for find to do it on your system because find is reimplemented on each system, it's a system utility. But if you want to write a portable app...
To be practical, it is reasonable to use system specific things like /etc/mtab and deal with porting matters elsewhere.
I would use popen(MOUNT_CMD) to read in the list of mounted directories, use Boost Regex to parse the output, put the mount points into a map<device,directory> and then traverse each directory in the map.
That should be portable to most Unix systems. You probably want to make MOUNT_CMD and MOUNT_REGEX external properties so they can be easily customized if you need to be very portable.