Knowledge Base

Preserving for the future: Shell scripts, AoC, and more

Cifs keepalive

Updated

This post originally talked about cifs-keepalive.sh, which is now bundled into the newer and more fully-featured shares.sh.

Overview

When a Linux system has a cifs mount to another server, sometimes it can time out. If you haven't used it in a while, the connection becomes stale. If you do an ls -l /mnt it might take a while, and then return a '/mnt/cifsdirectory not found' before displaying the directory contents.

Solution

My solution is a multi-tool script for network shares, which I simply call "shares." It's a part of my bgscripts package accessible on gitlab.

Code walkthrough

Obviously, there are many ways to implement this. All my script does is touch a file in a cifs mounted directory every couple of minutes. Check out its usage block from lines 18-33.

usage: shares.sh [-duV] [-r|-k] [-a] [-t <type>] [/mounted/directory [ ... ]]
version ${sharesversion}
-d debug Show debugging info, including parsed variables.
-u usage Show this usage block.
-V version Show script version number.
-r remount Remount shares
-k keepalive Touch shares to keep them from timing out
-a all All shares. Can be limited with -t. Default behavior if no directories provided.
-t <type> Only this type of share. Needs -a flag.
Return values:
0 Normal
1 Help or version info displayed
2 Invalid input options
3 Incorrect OS type
4 Unable to find dependency
5 Not run as root or sudo

The best way to run it is just with the -a flag. It will scan the currently mounted filesystems and list just the cifs/nfs ones as defined $validtypes. See lines 224-237,245:

# all currently mounted filesystems of the requested type
# get type, if requested
alltypes="$( echo "${validtypes}" | tr ' ' '|' )"
case "${type}" in
   "")
      searchstring="(${alltypes})"
      ;;
   *)
      if echo "${validtypes}" | grep -qiE "${type}" 1>/dev/null 2>&1;
      then
         searchstring="${type}"
      else
         searchstring="."
      fi

mount | grep -viE "${excludes}" | awk "/type ${searchstring}/{print \$3;}" >> "${tempfile1}"

And the actual keepalive command is just a touch --no-create, from lines 268-276.

keepalive)
   while read word;
   do
       debuglev 1 && echo "touching ${word}";
       touch --no-create "${word}/.fskeepalive" 1>/dev/null 2>&1
   done < "${tempfile1}"
   ;;

To make it run every three minutes, place a cron entry. Mine is in /etc/cron.d/shares-keepalive.cron :

*/3 *   *   *   *   root    /usr/share/bgscripts/shares.sh --all --keepalive 1>/dev/null 2>&1

Comments