#!/bin/sh #------------------------------------------------------------------------------ # /etc/init.d/nf-sclient - start script for nfs-client services # # Creation: 2004-08-12 jed # Last Update: $Id$ # # Copyright (c) 2021-@@YEAR@@ the eisfair team, team(at)eisfair(dot)org # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. #------------------------------------------------------------------------------ ### BEGIN INIT INFO # Provides: nfs # Required-Start: $network $rpcbind # Required-Stop: $network $rpcbind # Default-Start: 3 5 # Default-Stop: 0 1 2 6 # Short-Description: NFS client services. # Description: All necessary services for NFS clients ### END INIT INFO # read eislib etc. . /etc/init.d/functions # set package name package_name='nfs-client' # debug mode true/false #debug=true if ${debug:-false} then exec 2>/tmp/${package_name}-init-$$.log set -x ask_debug=true export ask_debug fi # make bash_completion happy bash_completion_string="Usage: ${0} {start|stop|status|restart}" # --------------------------------------------------------------------------- # usage # --------------------------------------------------------------------------- usage() { cat </dev/null } #------------------------------------------------------------------------------ # check if nfs4 support is required #------------------------------------------------------------------------------ check_nfs4_support() { local _cns_ret local _cns_idx local _cns_nfs_active local _cns_nfs_type _cns_ret=1 if [ "${NFS_CLIENT_SYSTEM_MOUNT:-no}" != "yes" ] then _cns_idx=1 while [ ${_cns_idx} -le ${NFS_CLIENT_MOUNT_N:-0} ] do eval _cns_nfs_active='${NFS_CLIENT_MOUNT_'${_cns_idx}'_ACTIVE}' if [ "${_cns_nfs_active}" != 'yes' ] then _cns_idx=$((${_cns_idx} + 1)) continue fi eval _cns_nfs_type='${NFS_CLIENT_MOUNT_'${_cns_idx}'_TYPE}' if [ "${_cns_nfs_type}" = 'nfs4' ] then _cns_ret=0 break fi _cns_idx=$((${_cns_idx} + 1)) done else # NFSCLIENT_PRELOAD_DAEMONS='yes', always load NFSv4 daemon _cns_ret=0 fi return ${_cns_ret} } #------------------------------------------------------------------------------ # mount rpc_pipefs #------------------------------------------------------------------------------ mount_rpc_pipefs() { # check if the file system is there yet case $(stat -c "%t" -f "${rpc_pipefs_dir}") in *67596969*) return 0 ;; esac /bin/mount -t rpc_pipefs rpc_pipefs "${rpc_pipefs_dir}" } #------------------------------------------------------------------------------ # umount rpc_pipefs #------------------------------------------------------------------------------ umount_rpc_pipefs() { case $(stat -c "%t" -f "${rpc_pipefs_dir}") in *67596969*) /bin/umount "${rpc_pipefs_dir}" ;; esac } #------------------------------------------------------------------------------ # mount all NFS drives mounted via the nfsclient package #------------------------------------------------------------------------------ mount_nfs_package_drives() { local _mnpd_idx local _mnpd_nfs_active local _mnpd_nfs_host local _mnpd_nfs_type local _mnpd_nfs_mount local _mnpd_nfs_dir local _mnpd_nfs_option local _mnpd_nfs_output=/tmp/${package_name}-mount-output.$$ # delete list of active nfsclient package mounts /usr/bin/rm -f ${nfsmount_file} _mnpd_idx=1 while [ ${_mnpd_idx} -le ${NFS_CLIENT_MOUNT_N:-0} ] do eval _mnpd_nfs_active='${NFS_CLIENT_MOUNT_'${_mnpd_idx}'_ACTIVE}' if [ -z "${_mnpd_nfs_active}" ] then _mnpd_nfs_active='no' fi if [ "${_mnpd_nfs_active}" != 'yes' ] then _mnpd_idx=$((${_mnpd_idx} + 1)) continue fi eval _mnpd_nfs_host='${NFS_CLIENT_MOUNT_'${_mnpd_idx}'_REMOTE_HOST}' eval _mnpd_nfs_type='${NFS_CLIENT_MOUNT_'${_mnpd_idx}'_TYPE}' eval _mnpd_nfs_mount='${NFS_CLIENT_MOUNT_'${_mnpd_idx}'_REMOTE_DIRECTORY}' eval _mnpd_nfs_dir='${NFS_CLIENT_MOUNT_'${_mnpd_idx}'_LOCAL_MOUNTPOINT}' eval _mnpd_nfs_option='${NFS_CLIENT_MOUNT_'${_mnpd_idx}'_OPTION}' if [ -n "${_mnpd_nfs_option}" ] then # explicitely set NFSv3 to prevent error messages # being displayed during automatic protocol evaluation if [ "${_mnpd_nfs_type}" = 'nfs' ] then echo "${_mnpd_nfs_option}" | /usr/bin/grep -q 'vers=3' if [ ${?} -ne 0 ] then _mnpd_nfs_option="vers=3,${_mnpd_nfs_option}" fi fi _mnpd_nfs_option="-o ${_mnpd_nfs_option}" else # explicitely set NFSv3 to prevent error messages # being displayed during automatic protocol evaluation if [ "${_mnpd_nfs_type}" = 'nfs' ] then _mnpd_nfs_option='-o vers=3' fi fi if [ ! -d ${_mnpd_nfs_dir} ] then /usr/bin/mkdir -p ${_mnpd_nfs_dir} fi # check if mountpoint is already used # server.privat.lan:/volume1/files on /mnt/files /bin/mount | /usr/bin/grep -q " on ${_mnpd_nfs_dir} " ret=${?} case ${ret} in 0) # if start package called twice ;-) # rewrite active nfs-client package mounts to file echo "${_mnpd_nfs_dir}" >> ${nfsmount_file} ;; *) boot_mesg " * Mounting share '${_mnpd_nfs_host}:${_mnpd_nfs_mount}' ..." /usr/bin/rm -f ${_mnpd_nfs_output} /bin/mount -t ${_mnpd_nfs_type} ${_mnpd_nfs_option} ${_mnpd_nfs_host}:${_mnpd_nfs_mount} ${_mnpd_nfs_dir} | /usr/bin/sed 's/^/ /g' >${_mnpd_nfs_output} 2>${_mnpd_nfs_output} if [ ${?} -eq 0 ] then echo_ok else echo_failure if [ -f ${_mnpd_nfs_output} ] then /usr/bin/cat ${_mnpd_nfs_output} fi fi /usr/bin/rm -f ${_mnpd_nfs_output} # write active nfsclient package mounts to file echo "${_mnpd_nfs_dir}" >> ${nfsmount_file} ;; esac _mnpd_idx=$((${_mnpd_idx} + 1)) done } #------------------------------------------------------------------------------ # umount all NFS drives mounted via the nfsclient package #------------------------------------------------------------------------------ umount_nfs_package_drives() { if [ -f ${nfsmount_file} ] then # list of NFS mounts exists while read NFSDIR do # check if share is currently mounted /bin/mount | /usr/bin/grep -q " on ${NFSDIR} " if [ ${?} -eq 0 ] then # if filesystems are not busy, wait for unmount to complete.. boot_mesg " * Unmounting share '${NFSDIR}' ..." /bin/umount ${NFSDIR} if [ ${?} -ne 0 ] then # if they are still busy, do a lazy unmount anyway /bin/umount -l ${NFSDIR} fi # check mount status /bin/mount | /usr/bin/grep -q " on ${NFSDIR} " if [ ${?} -ne 0 ] then echo_ok else echo_failure fi fi done < ${nfsmount_file} fi /usr/bin/rm -f ${nfsmount_file} } #------------------------------------------------------------------------------ # check if nfs drives have been mounted via /etc/fstab # return: 0 - nfs system drives exist # 1 - nfs system drives don't exist #------------------------------------------------------------------------------ nfs_system_drives() { local _nsd_ret=1 /usr/bin/sed 's/^ *//g' ${fstab_file} | /usr/bin/tr -s '[:space:]' | /usr/bin/cut -d' ' -f3 | /usr/bin/grep -E -q "^nfs|^nfs4" if [ ${?} -eq 0 ] then _nsd_ret=0 fi return ${_nsd_ret} } #------------------------------------------------------------------------------ # umount all nfs drives mounted via /etc/fstab #------------------------------------------------------------------------------ umount_nfs_system_drives() { local _unsd_nfs_dir if nfs_system_drives then # umount system drives /bin/mount | /usr/bin/grep 'type nfs' > ${nfsmount_tmpfile} while read LINE do _unsd_nfs_dir=$(echo "${LINE}" | /usr/bin/sed 's/^.* on \([-_./[:alnum:]]*\) .*$/\1/') if [ -f ${fstab_file} ] then # check if nfs drive is listed in /etc/fstab /usr/bin/grep -q " ${_unsd_nfs_dir} " ${fstab_file} if [ ${?} -eq 0 ] then # system mount match found, umount drive boot_mesg " * Unmounting share '${_unsd_nfs_dir}' ..." /bin/umount ${_unsd_nfs_dir} if [ ${?} -ne 0 ] then # if they are still busy, do a lazy unmount anyway /bin/umount -l ${_unsd_nfs_dir} fi # check mount status /bin/mount | /usr/bin/grep -q " on ${_unsd_nfs_dir} " if [ ${?} -ne 0 ] then echo_ok else echo_failure fi fi fi done < ${nfsmount_tmpfile} rm -f ${nfsmount_tmpfile} fi } #------------------------------------------------------------------------------ # kill proc #------------------------------------------------------------------------------ kill_proc() { proc=${1} for COUNT in 1 2 3 4 5 6 do if [ ${COUNT} -le 3 ] then # stop program the soft way (-15) /sbin/killproc -TERM ${proc} 2>/dev/null else # stop program the hard way (-9) /sbin/killproc -KILL ${proc} 2>/dev/null fi if ! checkproc ${proc} then # program stopped successfully kill_ret=0 break else sleep 1 fi done return ${kill_ret:-1} } #------------------------------------------------------------------------------ # start nfs-client #------------------------------------------------------------------------------ start_nfs_client() { local start_nfs4mods local _start_rpcprogs local _start_options local _start_nfs_line # See if rpcbind is running if [ -x /usr/sbin/rpcinfo ] then /usr/sbin/rpcinfo -p >/dev/null 2>&1 ret=${?} if [ ${ret} -ne 0 ] then boot_mesg " * Not starting: rpcbind is not running ..." echo_failure exit 0 fi fi # load kernel modules if necessary if check_nfs4_support then # load nfsd to prevent the following error messages: # rpc.idmapd: Opened /proc/net/rpc/nfs4.nametoid/channel # rpc.idmapd: Opened /proc/net/rpc/nfs4.idtoname/channel start_nfs4=true fi pidofproc -p /run/rpc.statd.pid -s /usr/sbin/rpc.statd case "${?}" in 0) boot_mesg " * NFS daemon 'rpc.statd' is already running ..." echo_warning ;; 1) /usr/bin/rm -f /run/rpc.statd.pid ;; 3) boot_mesg " * Starting NFS daemon 'rpc.statd' ..." loadproc /usr/sbin/rpc.statd --no-notify ;; esac load_modules sunrpc if [ "${START_NFS_CLIENT:-no}" = "yes" ] && [ ${NFS_CLIENT_MOUNT_N:-0} -gt 0 ] || [ "${NFS_CLIENT_SYSTEM_MOUNT:-no}" = "yes" ] then load_modules nfs fi if ${start_nfs4:-false} then load_modules nfsd fi # send reboot notifications to NFS peers /usr/sbin/sm-notify if ${start_nfs4:-false} then if mount_rpc_pipefs then pidofproc -s /usr/sbin/rpc.idmapd case "${?}" in 0) boot_mesg " * NFS daemon 'rpc.idmapd' is already running ..." echo_warning ;; 3) boot_mesg " * Starting NFS daemon 'rpc.idmapd' ..." loadproc /usr/sbin/rpc.idmapd ;; esac # boot_mesg " * Starting NFS daemon 'rpc.svcgssd' ..." # loadproc /usr/sbin/rpc.svcgssd fi fi # mount drives if [ "${NFS_CLIENT_SYSTEM_MOUNT:-no}" = "yes" ] then # make sure that all NFS shares will be mounted _start_nfs_flag=0 # check status of nfs system mounts /usr/bin/grep -E -q " nfs | nfs4 " ${fstab_file} if [ ${?} -eq 0 ] then /usr/bin/grep -E " nfs | nfs4 " ${fstab_file} > ${nfsmount_tmpfile} while read LINE do _start_nfs_line=$(echo "${LINE}" | /usr/bin/sed 's/^ *//g' | /usr/bin/cut -d' ' -f1) /bin/mount | /usr/bin/grep -q "^${_start_nfs_line} " if [ ${?} -ne 0 ] then # not yet mounted, mount it ... _start_nfs_flag=1 fi done < ${nfsmount_tmpfile} /usr/bin/rm -f ${nfsmount_tmpfile} fi if [ ${_start_nfs_flag} -eq 1 ] then boot_mesg " * Mounting all NFS system shares ..." /bin/mount -a -t nfs,nfs4 if [ ${?} -eq 0 ] then echo_ok else echo_failure fi fi fi if [ "${START_NFS_CLIENT:-no}" = "yes" ] && [ ${NFS_CLIENT_MOUNT_N:-0} -gt 0 ] then mount_nfs_package_drives fi if [ -f /run/nfs-server_start ] then /usr/sbin/service start nfs-server /usr/bin/rm -f /run/nfs-server_start fi } #------------------------------------------------------------------------------ # stop nfsclient #------------------------------------------------------------------------------ stop_nfs_client() { local _stop_rpcprogs local _stop_options local _stop_stopproc if [ ${NFS_CLIENT_MOUNT_N:-0} -gt 0 ] then # umount drives umount_nfs_package_drives fi if [ "${NFS_CLIENT_SYSTEM_MOUNT:-no}" = "yes" ] then # umount drives umount_nfs_system_drives fi # start nfs-server also, after restart nfs-client if [ -f /etc/rpcbind.d/nfs-server ] && [ ! -f /run/rpcbind_start ] then >/run/nfs-server_start /usr/sbin/service stop nfs-server fi pidofproc -s /usr/sbin/rpc.idmapd case "${?}" in 0) # boot_mesg " * Stopping NFS daemon 'rpc.svcgssd' ..." # killproc /usr/sbin/rpc.svcgssd # evaluate_retval boot_mesg " * Stopping NFS daemon 'rpc.idmapd' ..." kill_proc /usr/sbin/rpc.idmapd evaluate_retval ;; esac pidofproc -s /usr/sbin/rpc.statd case "${?}" in 0) boot_mesg " * Stopping NFS daemon 'rpc.statd' ..." kill_proc /usr/sbin/rpc.statd evaluate_retval ;; esac # umount rpc_pipefs umount_rpc_pipefs if ! basename $0 | grep -qE "^K[0-9][0-9]" then if /usr/bin/grep -q "^nfs" /proc/modules then # unload kernel modules boot_mesg " * Unloading NFS kernel modules ..." fi nfs_module='nfs auth_rpcgss rpcsec_gss_krb5 nfsd' for m_modul in ${nfs_module} do unload_modules ${m_modul} done evaluate_retval fi # remove run status file if [ -f ${nfsclient_run} ] then /usr/bin/rm -f ${nfsclient_run} fi } #------------------------------------------------------------------------------ # status of nfsclient #------------------------------------------------------------------------------ status_nfs_client() { local _status_rpcprogs local _status_pid local _status_idx local _status_nfs_flag local _status_nfs_active local _status_nfs_host local _status_nfs_mount local _status_nfs_line check_nfs=$(/usr/bin/grep "^nfs " /proc/modules) if [ -n "${check_nfs}" ] then boot_mesg "NFS kernel module 'nfs' loaded." ${INFO} else boot_mesg "NFS kernel module 'nfs' not loaded." ${INFO} fi statusproc /usr/sbin/rpc.statd if check_nfs4_support then statusproc /usr/sbin/rpc.idmapd # statusproc /usr/sbin/rpc.svcgssd fi # check status of nfsclient mounts _status_idx=1 while [ ${_status_idx} -le ${NFS_CLIENT_MOUNT_N:-0} ] do eval active='${NFS_CLIENT_MOUNT_'${_status_idx}'_ACTIVE}' if [ "${active}" != 'yes' ] then _status_idx=$((${_status_idx} + 1)) continue fi eval _status_nfs_host='${NFS_CLIENT_MOUNT_'${_status_idx}'_REMOTE_HOST}' eval _status_nfs_mount='${NFS_CLIENT_MOUNT_'${_status_idx}'_REMOTE_DIRECTORY}' /bin/mount | /usr/bin/grep -E "type *nfs[4]*" | /usr/bin/grep "^${_status_nfs_host}:${_status_nfs_mount} " > /dev/null if [ ${?} -eq 0 ] then boot_mesg "NFS share '${_status_nfs_host}:${_status_nfs_mount}' is mounted." ${INFO} else boot_mesg "NFS share '${_status_nfs_host}:${_status_nfs_mount}' is not mounted." ${INFO} fi _status_idx=$((${_status_idx} + 1)) done # check status of nfs system mounts /usr/bin/grep -E -q " nfs | nfs4 " ${fstab_file} if [ ${?} -eq 0 ] then /usr/bin/grep -E " nfs | nfs4 " ${fstab_file} > ${nfsmount_tmpfile} while read line do _status_nfs_line=$(echo "${line}" | sed 's/^ *//g' | cut -d' ' -f1) /bin/mount | /usr/bin/grep -q "^${_status_nfs_line} " if [ ${?} -eq 0 ] then # system mount match found, show it boot_mesg "NFS system share '${_status_nfs_line}' is mounted." ${INFO} else # other nfs mount boot_mesg "NFS system share '${_status_nfs_line}' is not mounted." ${INFO} fi done < ${nfsmount_tmpfile} rm -f ${nfsmount_tmpfile} fi } #============================================================================== # main #============================================================================== EXEC_CMD="$0 $*" config_file=/etc/config.d/${package_name} nfspmap_file=/run/${package_name}-pmap.list nfsclient_run=/run/${package_name}.run rpc_pipefs_dir=/var/lib/nfs/rpc_pipefs nfsmount_file=/run/${package_name}-mounts.list nfsmount_tmpfile=/tmp/${package_name}-mounts.$$ fstab_file=/etc/fstab NFS_CLIENT_PRELOAD_DAEMONS='no' . ${config_file} _quiet=false while [ 1 ] do case "$1" in *-quiet ) # suppress output _quiet=true shift ;; * ) cmd=$1 break ;; esac done case ${cmd} in mount ) mount_nfs_package_drives ;; umount|umountall ) umount_nfs_package_drives if [ "${cmd}" = 'umountall' ] then umount_nfs_system_drives fi ;; start) start_nfs_client ;; stop) stop_nfs_client ;; status) status_nfs_client ;; restart) stop_nfs_client sleep 2 start_nfs_client ;; *) usage exit 0 ;; esac exit #============================================================================== # end #============================================================================== exit 0