4

I want to use the functionality of umount -l, then remove the underlying device as safely as possible afterward.

  • I can't use umount --force to unmount the filesystem as it has become invisible to new processes.
  • I can't use lsof for an accurate list of the open files as the filesystem has become invisible to new processes.
  • If I use lsof before umount -l, there is a race contition of a new file being opened in between the two invocations.

I'm testing a work-around: sync && blockdev --setro /dev/<device>

The manual for blockdev --setro only says:

Set read-only.

Is the man page missing something? This seems to create a file on a --setro device:

# mount /dev/loop0 mountpoint/
# blockdev --setro /dev/loop0
# echo test > mountpoint/f
# sync
# umount mountpoint
# mount /dev/loop0 mountpoint/
mount: /tmp/mountpoint: WARNING: device write-protected, mounted read-only.
# cat mountpoint/f
test
#

Environment:

$ uname -a
Linux svelte 4.9.39-1-MANJARO #1 SMP PREEMPT Fri Jul 21 08:25:24 UTC 2017 x86_64 GNU/Linux
$ blockdev --version
blockdev from util-linux 2.30
Tom Hale
  • 30,455

1 Answers1

4

I guess blockdev --setro works similar to chmod: It affects only future openings of the object.

But I can offer a work-around for your detection problem:

  1. The /proc/$PID/cwd value is changed to / after the lazy unmount.
  2. The paths of open files of the process shown in /proc/$PID/fd are moved up to /, e.g. /mnt/tmp/output becomes /output.

So you can first filter all processes with cmd /. There may be false positives among them but this is very fast. The next step (not necessarily complete but probably faster) is to check /proc/$PID/fd of all these processes for files which do not exist at their shown paths.

The complete but probably not so fast check is to run stat for all files in /proc/$PID/fd. It shows the original device. So you might check this value before the umount to make things easier.

Hauke Laging
  • 90,279