From ba1bafc5acd5569df4ba21f7e940998f9877b0bf Mon Sep 17 00:00:00 2001 From: Mike Fleetwood Date: Sun, 5 Sep 2021 10:10:59 +0100 Subject: [PATCH] Replace /proc/mounts grep with Mount_Info cache reload and query (!89) Creating a grep process to check if a particular mount is still mounted is an unnecessary overhead. All that is needed is for the Mount_Info module to refresh it's copy of /proc/mounts and query that. To keep the code as simple as possible just reload the whole of the Mount_Info module and query the mount cache to determine if the particular block device is still mounted at this particular mount point. This therefore re-reads /proc/mounts (necessary) and /proc/swaps and /etc/fstab (unnecessary). This is still much less overhead than creating a separate grep process. Closes !89 - Fix unmount error when unmounting below a bind mount point --- include/Mount_Info.h | 1 + src/Mount_Info.cc | 12 ++++++++++++ src/Win_GParted.cc | 16 +++++++++------- 3 files changed, 22 insertions(+), 7 deletions(-) diff --git a/include/Mount_Info.h b/include/Mount_Info.h index e9310ddc..ae4a6513 100644 --- a/include/Mount_Info.h +++ b/include/Mount_Info.h @@ -49,6 +49,7 @@ public: static void load_cache(); static bool is_dev_mounted( const Glib::ustring & path ); static bool is_dev_mounted( const BlockSpecial & bs ); + static bool is_dev_mounted_at(const Glib::ustring& path, const Glib::ustring& mountpoint); static bool is_dev_mounted_readonly( const Glib::ustring & path ); static bool is_dev_mounted_readonly( const BlockSpecial & bs ); static std::vector get_all_mountpoints(); diff --git a/src/Mount_Info.cc b/src/Mount_Info.cc index 3794bce4..81dd5e44 100644 --- a/src/Mount_Info.cc +++ b/src/Mount_Info.cc @@ -136,6 +136,18 @@ const std::vector & Mount_Info::get_fstab_mountpoints( const Glib return find( fstab_info, path ).mountpoints; } + +// Return whether the device path, such as /dev/sda3, is mounted at mount point or not +bool Mount_Info::is_dev_mounted_at(const Glib::ustring& path, const Glib::ustring& mountpoint) +{ + const std::vector& mountpoints = get_mounted_mountpoints(path); + for (unsigned i = 0; i < mountpoints.size(); i++) + if (mountpoint == mountpoints[i]) + return true; + return false; +} + + // Private methods void Mount_Info::read_mountpoints_from_file( const Glib::ustring & filename, MountMapping & map ) diff --git a/src/Win_GParted.cc b/src/Win_GParted.cc index fcb086eb..ae7998f2 100644 --- a/src/Win_GParted.cc +++ b/src/Win_GParted.cc @@ -2847,14 +2847,16 @@ bool Win_GParted::unmount_partition( const Partition & partition, Glib::ustring } else { - Glib::ustring checkmount = "grep -w " + Glib::shell_quote(fs_mountpoints[i]) + " /proc/mounts"; - Glib::ustring cmd = "umount -v " + Glib::shell_quote( fs_mountpoints[i] ); - Glib::ustring dummy; - Glib::ustring umount_error; - - // Check mount point is still mounted - if (! Utils::execute_command(checkmount, dummy, umount_error)) + // Unmounting below a duplicating bind mount, unmounts all copies + // in one go so check if the file system is still mounted at this + // mount point before trying to unmount it. + Mount_Info::load_cache(); + if (Mount_Info::is_dev_mounted_at(partition.get_path(), fs_mountpoints[i])) { + Glib::ustring cmd = "umount -v " + Glib::shell_quote(fs_mountpoints[i]); + Glib::ustring dummy; + Glib::ustring umount_error; + if (Utils::execute_command(cmd, dummy, umount_error)) umount_errors.push_back("# " + cmd + "\n" + umount_error); }