# Howto: force umount of nfs when network is down

## Deedook

You who use nfs have probably had the problem a few times; the router dies, you pull the wrong plug, the nfs server hangs... there are quite a few reasons for it, and every time we get a nfs mount that can't be umounted because the nfs server can not be reached. I got tired of doing this by hand every time, and wrote a script. It is not the most beautiful script, but it does the work for me. Feel free to use it, improve it, distribute it or whatever. 

Disclaimer: Even if I haven't had any issues with the script, I take no responsibility whatsoever for what it does in any way.

Anyway, here it is:

```

#!/bin/bash

#Script to force umount of a dead nfs.

#Author: Daniel Marmander

#declare neccesary programs:

mount=`which mount`

grep=`which grep`

sed=`which sed`

cut=`which cut`

ping=`which ping` 

#Strip trailing slash from mount path:

mountpath=`echo ${1}| ${sed} -e "s/\/*$//"`

#Get the mount ip:

mountip=`${mount}|${grep} " ${mountpath}"|${cut} -d ":" -f 1`

#Check if we found the mount at all:

if [ "${mountip}" == "" ]; then

    echo ${mountpath}" was not found in mtab. Aborting."

    echo "Forced umount aborted.";

    exit 1

fi

echo ${mountpath} "linked to: " ${mountip}

#Check if the server is down, just to be sure:

echo "Checking if ${mountip} responds to ping."

${ping} -c 1 -t 1 ${mountip} > /dev/null  2>&1

if [ $? -eq 0 ]; then

    echo ${mountip} " responds to ping. Aborting.";

    echo "Forced umount aborted.";

else 

    echo ${mountip} " does not respond to ping. Forcing umount.";

    #Create fake fs

    ifconfig eth0:fakenfs ${mountip} netmask 255.255.255.255

    #Force umount

    umount -f -l ${mountpath}

    #Delete fake fs

    ifconfig eth0:fakenfs ${mountip} down

fi

```

----------

## Hu

 *Deedook wrote:*   

> 
> 
> ```
> #declare neccesary programs:
> 
> ...

 Why do this?  The shell is perfectly capable of finding these on its own if they are in $PATH.  If they are not in $PATH, then which will not find them either.

 *Deedook wrote:*   

> 
> 
> ```
> mountpath=`echo ${1}| ${sed} -e "s/\/*$//"`
> ```
> ...

 Since you are using bash, you can do this without calling out: mountpath="${1%/}".

 *Deedook wrote:*   

> 
> 
> ```
> mountip=`${mount}|${grep} " ${mountpath}"|${cut} -d ":" -f 1`
> ```
> ...

 In some cases, /etc/mtab might be outdated.  It would be better to check /proc/mounts, but that has a slightly different format, so you might need to change your grep expression.  Additionally, this line could produce bogus results if you have nested mounts, such that more than one line matches the grep expression.  Although it would be user error to attempt such an invocation, the results will likely be messy.  Also, since you specify no particular options to grep, any metacharacters in ${mountpath} will be interpreted.

 *Deedook wrote:*   

> 
> 
> ```
> if [ "${mountip}" == "" ]; then
> 
> ...

 It is traditional to print such messages to stderr.  :Wink: 

 *Deedook wrote:*   

> 
> 
> ```
> ifconfig eth0:fakenfs ${mountip} netmask 255.255.255.255
> ```
> ...

 Why do this?  If I recall correctly, a lazy unmount can successfully remove the mount point from the namespace without contacting the NFS server.  Using interface aliases is unnecessary if you use /sbin/ip from sys-apps/iproute2, which handles multiple addresses on a single interface in a more natural way.

----------

## Deedook

 *Hu wrote:*   

>  *Deedook wrote:*   
> 
> ```
> #declare neccesary programs:
> 
> ...

 

Yes, but if they don't, it will be easier to modify the script in order to find the programs. It's like declaring constants instead of using numerical values inside code. It doesn't matter until you have to change stuff.

 *Hu wrote:*   

> 
> 
>  *Deedook wrote:*   
> 
> ```
> ...

 

I agree. There are room for improvements, no doubt about it. But I won't do it  :P

 *Hu wrote:*   

>  *Deedook wrote:*   
> 
> ```
> if [ "${mountip}" == "" ]; then
> 
> ...

 

Yes... couldn't agree more. :) 

 *Hu wrote:*   

>  *Deedook wrote:*   
> 
> ```
> ifconfig eth0:fakenfs ${mountip} netmask 255.255.255.255
> ```
> ...

 

I don't know if you recall correctly or not, but it doesn't work for me. That's why I wrote the script from the beginning. I didn't put any energy into doing it naturally, I just wanted to get it to work, and I thought that I might as well share it, in case someone else had the same problem.  :)

----------

## Hu

 *Deedook wrote:*   

> Yes, but if they don't, it will be easier to modify the script in order to find the programs. It's like declaring constants instead of using numerical values inside code. It doesn't matter until you have to change stuff.

 True.  However, you could just as readily do mount=mount at the top, use $mount everywhere, and rely on $PATH if no one adds a better option.  Alternatively, you could use type -P program to search $PATH without a callout.  Regardless of whether you use which or type, it would be nice to add in || die, with an appropriate value of die, so that the script prints a helpful error and exits, rather than pushing on and exhibiting strange behavior.

 *Deedook wrote:*   

> There are room for improvements, no doubt about it. But I won't do it  

 Would you mind editing the known improvements into the top post, so that anyone who reads it later can benefit from them?  There is no need to make it perfect, but merging improvements that others have already written should be quick.  :Smile: 

 *Deedook wrote:*   

> I don't know if you recall correctly or not, but it doesn't work for me. That's why I wrote the script from the beginning. I didn't put any energy into doing it naturally, I just wanted to get it to work, and I thought that I might as well share it, in case someone else had the same problem.  

 When it fails for you, are you doing umount -f -l $mountpath or umount -l $mountpath?  When I know the server is down and want to detach anyway, I usually use just -l, without -f.

Either way, the script might be useful to someone, so thank you for posting it.

----------

