diff options
author | David Zeuthen <davidz@redhat.com> | 2007-03-01 03:45:01 -0500 |
---|---|---|
committer | David Zeuthen <davidz@redhat.com> | 2007-03-01 03:45:01 -0500 |
commit | 193b7bbb91cb56d5fa5e87e90382449a023b6915 (patch) | |
tree | 0090b9042ecd8fa9a35a8f0c05a9c66319d8a9e5 /tools | |
parent | 565868fe6c360abea4f9b8f855f8c86bc02ff44c (diff) |
fix detection of mounted volumes from yanked storage devices
This should fix some problems when mounted devices are yanked out. At
least that's the problem I had with my new 4GB SanDisk U3 Cruzer
Micro. I have two partitions on it - one cleartext vfat partition and
one LUKS partition. When yanking the stick, HAL nicely reported that
the cleartext partition was unmounted even though it was still
mounted. Which is a lie.
There's a race we don't handle. In particular, the device node for a
device, such as /dev/sdb1, may have been unlinked by udev but the
device is still mounted and we haven't processed the uevent for that
deletion from udev. So when we process entries from /proc/mounts we
fail to stat the device node /dev/sdb1 and this leads us to assume the
device is not mounted. That's wrong.
So in this case fall back to comparing on device names rather than
pretending the device is not mounted as that's what will happen if we
just skip this /proc/mounts entry.
The reason it's nicer to compare on major:minor, and why we do that in
general, is that /proc/mounts is *broken by design* - it contains the
*device name* passed to mount(2) which in some cases may be a
symlink. In fact, on many distros it's common to see /proc/mounts
contain /dev/root as the device for /.
Diffstat (limited to 'tools')
-rw-r--r-- | tools/hal-storage-cleanup-mountpoint.c | 5 |
1 files changed, 5 insertions, 0 deletions
diff --git a/tools/hal-storage-cleanup-mountpoint.c b/tools/hal-storage-cleanup-mountpoint.c index f4973a82..4c3b3172 100644 --- a/tools/hal-storage-cleanup-mountpoint.c +++ b/tools/hal-storage-cleanup-mountpoint.c @@ -154,18 +154,23 @@ do_cleanup (const char *mount_point) g_strfreev (lines); + printf ("removing directory", mount_point); + /* remove directory */ if (g_rmdir (mount_point) != 0) { unlink ("/media/.hal-mtab~"); unknown_error ("Cannot remove directory"); } + printf ("atomically creating new /media/.hal-mtab file"); + /* set new .hal-mtab file */ if (rename ("/media/.hal-mtab~", "/media/.hal-mtab") != 0) { unlink ("/media/.hal-mtab~"); unknown_error ("Cannot rename /media/.hal-mtab~ to /media/.hal-mtab"); } + printf ("hal-storage-cleanup-mountpoint done for %s", mount_point); } int |