Last updated on 2007-12-03@23:55. At my work the employees are in the fortunate position that they are free to choose whatever OS they want to work with. At the moment the default is still Windows XP but you are free to wipe the drive and install whatever you feel—as long as you can do your job properly. And there is work underway to roll our own distribution for internal use. You're even free to bring in your Mac (but we won't supply you with one). The only thing that's banned (unofficially) so far is Windows Vista. Server-side we run a mixture of Linux and Windows, and the thend is to replace broken Windows machines by Linux machines if possible. In such a heterogeneous environment it makes sense to share our files through Samba. It's one of the few protocols that any OS can speak.
If you're running Windows Server 2003 then you can't use the smbfs driver that most Linux distributions ship by default. Sorry, no "Places » Connect to server" for you GNOME folk. You'll need to use the CIFS filesystem driver and you'll need to edit /etc/fstab. Adding the required fstab entries is actually quite easy as I will show below, but on Debian and it's derivative distributions you get a nasty error when you subsequently try to reboot or shutdown your machine, which hangs for about 30 seconds waiting for a timeout:
- CIFS VFS: No Response for Cmd <number> mid <number>
It took me quite a bit of time to properly solve that one, but in the end it turned out to be quite simple. I will show you later in the article, but let's start mounting first.
Mounting Samba shares with CIFS
Editing your /etc/fstab file is the easiest way to automatically mount your Samba shares, even if you use a laptop and travel around from network to network. Here is how your fstab entry should look (other filesystems excluded):
- # /etc/fstab: static file system information.
- #
- # <file system> <mount point> <type> <options> <dump> <pass>
- //<server>/<share> <mount point> cifs rw,_netdev,user=<username>,password=<password>,uid=<uid>,gid=<gid> 0 0
Most of the options are pretty straightforward. If you are mounting shares from a Windows server, make sure that you specify the username as DOMAIN/username, where DOMAIN is your Windows domain/workgroup. For <uid> and <gid> you should specify the userid/groupid that the share should be mounted as. You can lookup the numeric IDs in /etc/passwd and /etc/group.
Also notice that I have specified the _netdev option. CIFS doesn't know about this option and will throw a warning about it, but you should leave it in. This option ensures that the drives won't get mounted if you have no network or if you are on the wrong network. It also makes sure your shares get mounted/unmounted when you switch networks. That's because Debian's if* scripts are triggered when your network configuration changes, and they watch all the filesystems with the _netdev option and do the right thing automagically.
Getting rid of the “CIFS VFS: No Response” errors
If you have your Samba shares mounted through fstab like described above, you have probably come across this error when you reboot or shutdown, accompanied by a 30 second pause, waiting for a timeout:
- CIFS VFS: Server not responding
- CIFS VFS: No response for cmd <number> mid <number>
This problem has been bugging me for quite a while before I dug into it. As it turns out, cifs runs via a separate daemon process called cifsd. By the time that the shutdown/reboot init scripts start unmounting network filesystems, the daemon has already been killed by the system. And in there is a nice catch-22: All processes must be killed before you start unmounting volumes and with CIFS, you need to unmount first, then kill the process. And there was no way that I could create an exception in the "Shutting down all processes..." phase for the processes required by CIFS.
To solve it I wrote a little script cobbled together from bits and pieces of the umountnfs.sh and sendsigs init scripts. Basically it makes a list of all your mounted CIFS filesystems, shuts down and subsequently kills all processes that are still using those filesystems, and finally unmounts the CIFS filesystems. Save it to /etc/init.d/umountcifs and make it executable. Then symlink to it from /etc/rc0.d and /etc/rc6.d. You should ensure that umountcifs runs before the K20* init scripts fire. If it runs at K20 or later, you will still get the error. Personally I symlinked from /etc/rc(0|6).d/K19umountcifs.
Updated on 2007-12-03@23:55. Neill Hogarth adds that for (K)ubuntu 7.10 the script should be symlinked as K12umountcifs. K19 seems to work on (K)ubuntu 7.04 and lower, and on Debian Etch.
To conclude, here is the script I built (or download it here):
- #! /bin/sh
- ### BEGIN INIT INFO
- # Provides: umountcifs
- # Required-Start:
- # Required-Stop: umountcifs
- # Should-Stop:
- # Default-Start:
- # Default-Stop: 0 6
- # Short-Description: Unmount all cifs filesystems and terminate all processes using them
- # Description:
- ### END INIT INFO
- PATH=/sbin:/usr/sbin:/bin:/usr/bin
- KERNEL="$(uname -s)"
- RELEASE="$(uname -r)"
- . /lib/init/vars.sh
- . /lib/lsb/init-functions
- case "${KERNEL}:${RELEASE}" in
- Linux:[01].*|Linux:2.[01].*)
- FLAGS=""
- ;;
- Linux:2.[23].*|Linux:2.4.?|Linux:2.4.?-*|Linux:2.4.10|Linux:2.4.10-*)
- FLAGS="-f"
- ;;
- *)
- FLAGS="-f -l"
- ;;
- esac
- do_stop () {
- #
- # Make list of points to unmount in reverse order of their creation
- #
- exec 9<&0 </etc/mtab
- DIRS=""
- while read DEV MTPT FSTYPE OPTS REST
- do
- case "$MTPT" in
- /|/proc|/dev|/dev/pts|/dev/shm|/proc/*|/sys|/lib/init/rw)
- continue
- ;;
- /var/run)
- if [ yes = "$RAMRUN" ] ; then
- continue
- fi
- ;;
- /var/lock)
- if [ yes = "$RAMLOCK" ] ; then
- continue
- fi
- ;;
- esac
- case "$FSTYPE" in
- cifs)
- DIRS="$MTPT $DIRS"
- ;;
- esac
- done
- exec 0<&9 9<&-
- if [ "$DIRS" ]
- then
- # Kill all processes using the cifs volumes
- PROCESSES=""
- for DIR in $DIRS; do
- PROCESS=`fuser -m $DIR`
- if [ "$PROCESS" ]; then
- PROCESSES="$PROCESS $PROCESSES"
- fi
- done
- if [ "$PROCESSES" ]
- then
- log_action_begin_msg "Asking all processes using cifs filesystems to terminate"
- echo "kill -15 $PROCESSES"
- log_action_end_msg 0
- for seq in 1 2 3 4 5 ; do
- # use SIGCONT/signal 18 to check if there are
- # processes left. No need to check the exit code
- # value, because either killall5 work and it make
- # sense to wait for processes to die, or it fail and
- # there is nothing to wait for.
- echo "kill -18 $PROCESSES > /dev/null 2>&1" || break
- sleep 1
- done
- log_action_begin_msg "Killing all remaining processes using cifs filesystems"
- echo "kill -9 $PROCESSES > /dev/null 2>&1" # SIGKILL
- log_action_end_msg 0
- fi
- # Unmount all cifs filesystems
- [ "$VERBOSE" = no ] || log_action_begin_msg "Unmounting remote and non-toplevel cifs filesystems"
- umount $FLAGS $DIRS
- ES=$?
- [ "$VERBOSE" = no ] || log_action_end_msg $ES
- fi
- }
- case "$1" in
- start)
- # No-op
- ;;
- restart|reload|force-reload)
- echo "Error: argument '$1' not supported" >&2
- exit 3
- ;;
- stop|"")
- do_stop
- ;;
- *)
- echo "Usage: umountcifs [start|stop]" >&2
- exit 3
- ;;
- esac
- :
Comments
#1 rodd ahrenstorff (http://ahrenstorff.us)
#2 Sander Marechal (http://www.jejik.com)
There's quite a long thread on the Ubuntu forums that deals with this.
My solution is in there, alongside someone else's solution:
http://ubuntuforums.org/showthread.php?t=293513
To explain the bit about the piece you quoted, you need to understand
runlevels first. Google for it. There are plenty of good resources on
it. The bit that matters is this: When you shut down your system, all
the scripts in /etc/rc0.d are run. First all the scripts named Sxx
numbers (ascending), then all the scripts with Kxx (also in ascending
order). When you reboot, all the scripts in /etc/rc6.d instead of
/etc/rc0.d are run. Those scripts together form the shutdown and reboor
sequence of your machine.
What you need to do is put my script in those sequences. There best way
is to put my script in /etc/init.d and then create links to it from the
rc0.d and rc6.d directories. You do that with:
This means that the script will be executed after K18xxx and before
K20xxx, which is the right location for Debian Etch and Ubuntu Feisty.
From the comments in the Ubuntu forum I understand that the shutdown and
reboot sequence changed a bit for Gutsy, so if you use Gutsy then the
script needs to run sooner. For example, at K12 instead of K19.
Just experiment. Create the links and shutdown/reboot. If you still get
the error, the script needs to run sooner. So remove the links (with
"rm") and recreate them with a lower K number. Then try again.
Hope this helps!
#3 Anibal (http://www.anibalnet.nl)
Cheers
Anibal
#4 Sander Marechal (http://www.jejik.com)
#5 Anonymous Coward
I am a bit thick, I have tried all permutations of the cifs smbfs to try and mount a windows shared folder. The folder contains video I want to stream to my linux m/c's.
Here are the lines I have added to /etc/fstab:
//192.168.2.5/Public /media/public smbfs guest 0 0
This mounts my NAS drive no problem.
so I tried similar to mount my windows shared drive called 'videos', domain is workgroup, pc is called 'apwdesktoppc', my windows user name is 'Anthony Ward'
//192.168.2.2/Videos /media/videos cifs rw,WORKGROUP,APWDESKTOPPC=Anthony Ward,password=********
I get an error message:
mount error 22 = Invalid argument
Refer to the mount.cifs(8) manual page (e.g.man mount.cifs)
Any suggestions as to what I am doing wrong, please?
#6 Sander Marechal (http://www.jejik.com)
//192.168.2.2/Videos /media/videos cifs rw,WORKGROUP,APWDESKTOPPC="Anthony Ward",password=********
//192.168.2.2/Videos /media/videos cifs rw,WORKGROUP,"APWDESKTOPPC=Anthony Ward",password=********
//192.168.2.2/Videos /media/videos cifs rw,WORKGROUP,APWDESKTOPPC=Anthony\ Ward,password=********
#7 Randy Klein
#8 Oliver Doepner (http://doepner.net/)
sudo update-rc.d umountcifs stop 19 0 6 .
Adding system startup for /etc/init.d/umountcifs ...
/etc/rc0.d/K19umountcifs -> ../init.d/umountcifs
/etc/rc6.d/K19umountcifs -> ../init.d/umountcifs
#9 Sander Marechal (http://www.jejik.com)
#10 Oliver Doepner (http://doepner.net/)
But I had to set the numeric priority to 12 (i.e. K12umountcifs) so that it runs before K14network-manager.
#11 j1nn (http://jinn.mine.nu)
#12 Anonymous Coward
#13 JT
Comments have been retired for this article.