RHEL Engineering is moving the tracking of its product development work on RHEL 6 through RHEL 9 to Red Hat Jira (issues.redhat.com). If you're a Red Hat customer, please continue to file support cases via the Red Hat customer portal. If you're not, please head to the "RHEL project" in Red Hat Jira and file new tickets here. Individual Bugzilla bugs in the statuses "NEW", "ASSIGNED", and "POST" are being migrated throughout September 2023. Bugs of Red Hat partners with an assigned Engineering Partner Manager (EPM) are migrated in late September as per pre-agreed dates. Bugs against components "kernel", "kernel-rt", and "kpatch" are only migrated if still in "NEW" or "ASSIGNED". If you cannot log in to RH Jira, please consult article #7032570. That failing, please send an e-mail to the RH Jira admins at rh-issues@redhat.com to troubleshoot your issue as a user management inquiry. The email creates a ServiceNow ticket with Red Hat. Individual Bugzilla bugs that are migrated will be moved to status "CLOSED", resolution "MIGRATED", and set with "MigratedToJIRA" in "Keywords". The link to the successor Jira issue will be found under "Links", have a little "two-footprint" icon next to it, and direct you to the "RHEL project" in Red Hat Jira (issue links are of type "https://issues.redhat.com/browse/RHEL-XXXX", where "X" is a digit). This same link will be available in a blue banner at the top of the page informing you that that bug has been migrated.
Bug 803799 - [util-linux/mount/umount.c] umount -d does not check for LD_FLAGS_AUTOCLEAR flag
Summary: [util-linux/mount/umount.c] umount -d does not check for LD_FLAGS_AUTOCLEAR flag
Keywords:
Status: CLOSED NOTABUG
Alias: None
Product: Red Hat Enterprise Linux 7
Classification: Red Hat
Component: util-linux
Version: 7.0
Hardware: Unspecified
OS: Unspecified
unspecified
unspecified
Target Milestone: rc
: ---
Assignee: Karel Zak
QA Contact:
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2012-03-15 16:50 UTC by Boris Ranto
Modified: 2012-04-02 16:06 UTC (History)
0 users

Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Clone Of:
Environment:
Last Closed: 2012-04-02 16:06:27 UTC
Target Upstream Version:
Embargoed:


Attachments (Terms of Use)

Description Boris Ranto 2012-03-15 16:50:18 UTC
Description of problem:
The umount command (with -d option) in rhel7 will attempt to release loop device even when it is set to be cleared automatically (LD_FLAGS_AUTOCLEAR).

Version-Release number of selected component (if applicable):
util-linux-2.20.1

How reproducible:
Always

Steps to Reproduce:
1. truncate -s 5G fs.img; mkfs.xfs fs.img
2. mount -o loop fs.img /media
3. umount -d /media
  
Actual results:
Umount tries to release the loop device that is set to be cleared automatically.

Expected results:
Umount does not try to release the loop device once it was already released.

Additional info:
This seems to be caused by a missing condition in mount/umount.c:303 (although the commentary references the missing condition):
299         /*
300          * Ignore the option "-d" for non-loop devices and loop devices with
301          * LO_FLAGS_AUTOCLEAR flag.
302          */
303         if (delloop && is_loop_device(spec))
304                 myloop = 1;
305 

Further looking at the code, the condition just moved to line 411, the problem is that the condition is called once the umount unmounted the file system (and even released the loop device in case of the autoclear mechanism). This means that the condition will be satisfied and the umount command will attempt to release a loop device that was already released.

I've tested the umount behaviour with the following simple patch and it fixed the issue for me:

--- mount/umount-old.c	2012-03-15 11:34:41.294141058 -0400
+++ mount/umount.c	2012-03-15 11:45:43.900117187 -0400
@@ -300,7 +300,7 @@ umount_one (const char *spec, const char
 	 * Ignore the option "-d" for non-loop devices and loop devices with
 	 * LO_FLAGS_AUTOCLEAR flag.
 	 */
-	if (delloop && is_loop_device(spec))
+	if (delloop && is_loop_device(spec) && !is_loop_autoclear(spec))
 		myloop = 1;
 
 	if (restricted) {
@@ -408,7 +408,7 @@ umount_one (const char *spec, const char
 			loopdev = spec;
 	}
  gotloop:
-	if (loopdev && !is_loop_autoclear(loopdev))
+	if (loopdev)
 		del_loop(loopdev);
 
  writemtab:

I suspect that the reason for the move was to fix the cases when the loop autoclear mechanism fails (this occurred several times while using xfstests test no. 073). Then it would probably make more sense to move the condition completely. The problem is that if we move the condition completely it will succeed trivially for a released loop device (the device will be a loop device and it will not have the autoclear flag set) and the code will try to release already released device, again.
In this case the best fix would probably be to check that the device is assigned and without the autoclear flag, i.e something like this (assuming the function is_loop_assigned is defined somewhere else and tests whether the given device is an assigned loop device):

--- mount/umount-old.c	2012-03-15 11:34:41.294141058 -0400
+++ mount/umount.c	2012-03-15 12:42:02.171998383 -0400
@@ -271,7 +271,6 @@ umount_one (const char *spec, const char
 	int extra_flags = 0;
 	const char *loopdev, *target = node;
 	char *targetbuf = NULL;
-	int myloop = 0;
 
 	/* Special case for root.  As of 0.99pl10 we can (almost) unmount root;
 	   the kernel will remount it readonly so that we can carry on running
@@ -296,12 +295,6 @@ umount_one (const char *spec, const char
 	/* Skip the actual umounting for --fake */
 	if (fake)
 		goto writemtab;
-	/*
-	 * Ignore the option "-d" for non-loop devices and loop devices with
-	 * LO_FLAGS_AUTOCLEAR flag.
-	 */
-	if (delloop && is_loop_device(spec))
-		myloop = 1;
 
 	if (restricted) {
 		if (umount_nofollow_support())
@@ -403,12 +396,16 @@ umount_one (const char *spec, const char
 				node = mc->m.mnt_dir;
 		}
 
-		/* Also free loop devices when -d flag is given */
-		if (myloop)
+		/* Also attemp to free loop devices when -d flag is given */
+		if (delloop)
 			loopdev = spec;
 	}
  gotloop:
-	if (loopdev && !is_loop_autoclear(loopdev))
+	/*
+	 * Ignore the option "-d" for non-loop devices and loop devices with
+	 * LO_FLAGS_AUTOCLEAR flag.
+	 */
+	if (loopdev && is_loop_assigned(loopdev) && !is_loop_autoclear(loopdev))
 		del_loop(loopdev);
 
  writemtab:

Comment 1 Karel Zak 2012-04-02 16:06:27 UTC
For RHEL7 we will use util-linux 2.21 where is pure libmount based umount(8)(rebase requested :bug #804780).

Anyway, I have ported your patch to the current upstream code, because old mount(8) is still upstream default. (commit 72bec4d0dd5c94f15ed7c17d3452ba87ed737209)


Note You need to log in before you can comment on or make changes to this bug.