Bug 57283 - service netfs stop fails to unmount loopback mounts on first try
service netfs stop fails to unmount loopback mounts on first try
Status: CLOSED RAWHIDE
Product: Red Hat Linux
Classification: Retired
Component: initscripts (Show other bugs)
7.2
i686 Linux
medium Severity low
: ---
: ---
Assigned To: Bill Nottingham
Brock Organ
:
Depends On:
Blocks:
  Show dependency treegraph
 
Reported: 2001-12-08 13:09 EST by Avi Kivity
Modified: 2014-03-16 22:24 EDT (History)
2 users (show)

See Also:
Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of:
Environment:
Last Closed: 2001-12-10 15:07:41 EST
Type: ---
Regression: ---
Mount Type: ---
Documentation: ---
CRM:
Verified Versions:
Category: ---
oVirt Team: ---
RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: ---


Attachments (Terms of Use)

  None (edit)
Description Avi Kivity 2001-12-08 13:09:08 EST
From Bugzilla Helper:
User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:0.9.6) Gecko/20011120

Description of problem:
I have some loopback mounts in /etc/fstab:

/root/rh72/iso/enigma-i386-disc1.iso /redhat/1  iso9660 ro,loop         0 0
/root/rh72/iso/enigma-i386-disc2.iso /redhat/2  iso9660 ro,loop         0 0

Running 'service netfs stop' (or shutting down the system) fails to
unmount them first, then a retry (initiated ny /etc/rc.d/init.d/netfs
itself) succeeds.

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


How reproducible:
Always

Steps to Reproduce:
1. Add a loopback mount to /etc/fstab.
2. Mount it.
3. 'service netfs stop'

Actual Results:  There is an error message, a delay, then a sucess
message. The unmount is performed as expected.

Expected Results:  No error message, and a successful unmount.

Additional info:

The following patch fixes it.

--- netfs.bad   Sat Dec  8 19:49:02 2001
+++ netfs       Sat Dec  8 19:49:23 2001
@@ -45,7 +45,7 @@
        ;;
   stop)
         # Unmount loopback stuff first
-       remaining=`awk '!/^#/ && $1 ~ /^\/dev\/loop/ && $2 != "/" {print
$1}' /proc/mounts`
+       remaining=`awk '!/^#/ && $1 ~ /^\/dev\/loop/ && $2 != "/" {print
$2}' /proc/mounts`
        [ -n "$remaining" ] && {
                sig=
                retry=3
Comment 1 Zenon Mousmoulas 2001-12-10 01:17:21 EST
I don't think that's right. $1 in this awk program prints the device name 
from /proc/mounts. $2 would print the mountpoint. `umount' (line 55, 57) would 
work with either, but the device name is needed to be passed as an argument to 
`losetup' (line 60, 61) and `fuser' (line 65) later on. In my experience, the 
`netfs' init script will manage to unmount the loop device on the first try, 
as long as the device is not busy. Even then though, it will manage to unmount 
it without a retry, as long as `fuser' doesn't take longer than 5 seconds to 
kill all processes using the device (with the default signal 9 [SIGKILL], not 
the custom $sig [again signal 9 though], because the variable is null on the 
first attempt).
I don't understand why it doesn't work for you. Perhaps you can run this test 
if you want, so I can see what's happening in your case:
1. Start the system and make sure your loop devices are mounted.
2. Run the netfs script like this, so the both stdout and stderr output is 
logged in a file. Replace /tmp/somefile with anything you like, but make sure 
you do the stderr redirection too:
bash -x /etc/rc.d/init.d/netfs stop >/tmp/somefile 2>&1
3. attach this file to this bug so I can take a look at it.

Please see Bug # for some bugs I have found in the netfs script.
Comment 2 Zenon Mousmoulas 2001-12-10 02:48:24 EST
I'm sorry, one correction:

`umount' (line 55, 57) would work with either, but the device name is needed 
to be passed as an argument to `losetup' (line 60, 61) and `fuser' (line 65) 
later on.

'fuser' will handle the mountpoint just fine, same as 'umount', only 'losetup' 
requires the loop device name.

Also, I forgot to give the number for the bug I mentioned:
Bug #57314
Comment 3 Avi Kivity 2001-12-10 08:46:46 EST
Umm... umount will detach the loop device if it appears int /etc/mtab; see also
the -d option for umount (which detaches the loop device for loopback mounts).
losetup is completely unnecessary.

Following is the output from service netfs stop without the patch applied:

[avi@firebolt ~]# service netfs stop
Unmounting loopback filesystems:  umount: /dev/loop0: not mounted
umount: /dev/loop1: not mounted
                                                           [FAILED]
Detaching loopback device /dev/loop0:  ioctl: LOOP_CLR_FD: Device or resource busy
                                                           [FAILED]
Detaching loopback device /dev/loop1:  ioctl: LOOP_CLR_FD: Device or resource busy
                                                           [FAILED]
Unmounting loopback filesystems (retry):                   [  OK  ]
[avi@firebolt ~]#

Apply the patch, and:

[avi@firebolt ~]# service netfs start
Mounting other filesystems:                                [  OK  ]
[avi@firebolt ~]# service netfs stop
Unmounting loopback filesystems:                           [  OK  ]
[avi@firebolt ~]#

Updated patch (losetup removed)

[avi@firebolt ~]# diff -u /etc/rc.d/init.d/netfs{.bad,}
--- /etc/rc.d/init.d/netfs.bad  Sat Dec  8 19:49:02 2001
+++ /etc/rc.d/init.d/netfs      Mon Dec 10 15:40:34 2001
@@ -45,21 +45,17 @@
        ;;
   stop)
         # Unmount loopback stuff first
-       remaining=`awk '!/^#/ && $1 ~ /^\/dev\/loop/ && $2 != "/" {print $1}'
/proc/mounts`
+       remaining=`awk '!/^#/ && $1 ~ /^\/dev\/loop/ && $2 != "/" {print $2}'
/proc/mounts`
        [ -n "$remaining" ] && {
                sig=
                retry=3
                while [ -n "$remaining" -a "$retry" -gt 0 ]
                do
                        if [ "$retry" -lt 3 ]; then
-                               action $"Unmounting loopback filesystems
(retry):" umount $remaining
+                               action $"Unmounting loopback filesystems
(retry):" umount -d $remaining
                        else
-                               action $"Unmounting loopback filesystems: "
umount $remaining
+                               action $"Unmounting loopback filesystems: "
umount -d $remaining
                        fi
-                       for dev in $remaining ; do
-                               losetup $dev >/dev/null 2>&1 && \
-                               action $"Detaching loopback device $dev: "
losetup -d $dev
-                       done
                        remaining=`awk '!/^#/ && $1 ~ /^\/dev\/loop/ && $2 !=
"/" {print $2}' /proc/mounts`
                        [ -z "$remaining" ] && break
                        /sbin/fuser -k -m $sig $remaining >/dev/null

I've tested the patch, and it
- kills processes that use the mount (if any)
- correctly detaches the loop device
Comment 4 Zenon Mousmoulas 2001-12-10 13:21:50 EST
I am sorry, you are right :)
It seems 'umount' needs the mountpoint of the loop device and not the loop 
device's name, that's why it fails in the first place, so the error from 
losetup  (ioctl: LOOP_CLR_FD: Device or resource busy) occurs because the 
device is still mounted. You are right, you don't even need 'losetup -d' 
anymore, 'umount' will do it all for you, and I also noticed that 'umount' 
doesn't even need the -d switch; if it finds the loop option in mtab, it will 
free the associated loop device automatically.
However losetup could still be in this script for compatibility/redundancy 
reasons, for versions of 'umount' that could not do this automatically. I 
don't know, this is just an idea...
As for your patch, if there are indeed compatibility issues, e.g. a version of 
umount where -d would be considered a bogus option, then I think you should 
only change that $1 to $2 in the awk program. If a current version of umount 
is used, the filesystem will be unmounted and the loop device automatically 
freed, so 'losetup' won't find a loop dev and 'losetup -d' won't even run; the 
loop will break right after that since $remaining will be now null. However if 
there are no compatibility concerns, then you should indeed go ahead and 
remove the losetup code as well, as it's certainly not necessary. In either 
case, I don't think you need to add the -d option to umount, I am assuming the 
option loop will appear in mtab.
Comment 5 Zenon Mousmoulas 2001-12-10 13:29:38 EST
It looks like there are no compatibility issues involved, 'rpm -q initscripts -
-requires' says "mount >= 2.11g-5" is required, which is the currently 
shipping (in RHL 7.2) version of mount, so you should go ahead and remove 
the 'losetup' commands.
I will combine your patch with mine (for the errors I reported in Bug #57314) 
and attach it there. I hope Red Hat people will read both threads and take 
care of it :)
Comment 6 Zenon Mousmoulas 2001-12-10 15:07:32 EST
It looks like there is an updated initscripts rpm package in RawHide 
(initscripts-6.40.2-1). I installed it and it looks like the issue you 
reported has been addressed. They use a different approach, but the problem is 
solved: no errors when running 'service netfs stop' & the loop devices are 
unmounted properly on the first try.
Here is the relevant part of the script:

(/etc/init.d/netfs, line 47-72)

        # Unmount loopback stuff first
        remaining=`awk '!/^#/ && $1 ~ /^\/dev\/loop/ && $2 != "/" {print 
$2}' /proc/mounts`
        devremaining=`awk '!/^#/ && $1 ~ /^\/dev\/loop/ && $2 != "/" {print 
$1}' /proc/mounts`
        [ -n "$remaining" ] && {
                sig=
                retry=3
                while [ -n "$remaining" -a "$retry" -gt 0 ]
                do
                        if [ "$retry" -lt 3 ]; then
                                action $"Unmounting loopback filesystems 
(retry):" umount $remaining
                        else
                                action $"Unmounting loopback filesystems: " 
umount $remaining
                        fi
                        for dev in $devremaining ; do
                                losetup $dev >/dev/null 2>&1 && \
                                action $"Detaching loopback device $dev: " 
losetup -d $dev
                        done    
                        remaining=`awk '!/^#/ && $1 ~ /^\/dev\/loop/ && $2 !
= "/" {print $2}' /proc/mounts`
                        devremaining=`awk '!/^#/ && $1 ~ /^\/dev\/loop/ && $2 !
= "/" {print $1}' /proc/mounts`
                        [ -z "$remaining" ] && break
                        /sbin/fuser -k -m $sig $remaining >/dev/null
                        sleep 5
                        retry=$(($retry -1))
                        sig=-9
                done
        }
Comment 7 Avi Kivity 2001-12-10 15:20:45 EST
I believe my patch is better, though. I am marking bug as closed, resolution
RAWHIDE. Hope that's the right thing to do (I'm a bugzilla newbie).

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