immortalwrt/package/jsda/luci-app-nfs/files/root/etc/init.d/nfs
2019-07-02 18:06:49 +08:00

245 lines
6.4 KiB
Bash
Executable File

#!/bin/sh /etc/rc.common
START=45
STOP=99
EXTRA_COMMANDS="firewall restart"
APP="nfs"
check_nfsd() {
pidof nfsd &>/dev/null && return 0
return 1
}
get_lan_wan_ip() {
[ -z "$1" ] && return 1
ip=''
. /lib/functions/network.sh>/dev/null
network_get_ipaddr ip $1>/dev/null && echo "$ip"
}
iptables_init() {
INPUT="INPUT"
iptables -t filter --list zone_wan_input &>/dev/null && INPUT="zone_wan_input"
PREROUTING="PREROUTING"
iptables -t nat --list zone_wan_prerouting &>/dev/null && PREROUTING="zone_wan_prerouting"
[ -z "$LAN_IP" ] && {
LAN_IP=$(get_lan_wan_ip 'lan')
[ -z "$LAN_IP" ] && return 1
}
if [ "$external_access" = '1' ]; then
RULES_NAT="*nat
-A $PREROUTING -p udp -m udp --dport 111 -m comment --comment \"NFS\" -j DNAT --to-destination $LAN_IP:111
-A $PREROUTING -p tcp -m tcp --dport 111 -m comment --comment \"NFS\" -j DNAT --to-destination $LAN_IP:111
-A $PREROUTING -p udp -m udp --dport 2049 -m comment --comment \"NFS\" -j DNAT --to-destination $LAN_IP:2049
-A $PREROUTING -p tcp -m tcp --dport 2049 -m comment --comment \"NFS\" -j DNAT --to-destination $LAN_IP:2049
-A $PREROUTING -p udp -m udp --dport 32777 -m comment --comment \"NFS\" -j DNAT --to-destination $LAN_IP:32777
-A $PREROUTING -p tcp -m tcp --dport 32777 -m comment --comment \"NFS\" -j DNAT --to-destination $LAN_IP:32777
-A $PREROUTING -p udp -m udp --dport 32780 -m comment --comment \"NFS\" -j DNAT --to-destination $LAN_IP:32780
-A $PREROUTING -p tcp -m tcp --dport 32780 -m comment --comment \"NFS\" -j DNAT --to-destination $LAN_IP:32780
COMMIT"
else
SOURCE="-s ${LAN_IP%.*}.0/24 "
fi
RULES_FILTER="*filter
-A $INPUT ${SOURCE}-p udp -m udp --dport 111:2049 -m comment --comment \"NFS\" -j ACCEPT
-A $INPUT ${SOURCE}-p tcp -m tcp --dport 111:2049 -m comment --comment \"NFS\" -j ACCEPT
-A $INPUT ${SOURCE}-p udp -m udp --dport 32777:32780 -m comment --comment \"NFS\" -j ACCEPT
-A $INPUT ${SOURCE}-p tcp -m tcp --dport 32777:32780 -m comment --comment \"NFS\" -j ACCEPT
COMMIT"
return 0
}
iptables_run() {
[ -z "$1" -o -z "$2" ] && return 1
RUN_RUNLES=$(echo -e "$1"|grep -Eo '[-][A].*')
[ "$3" = '-D' ] && RUN_RUNLES=$(echo -e "$RUN_RUNLES"|sed -E 's/^-[AI]/-D/')
while read RULE
do
eval "iptables -t $2 $RULE"
done <<-EOF
$(echo -e "$RUN_RUNLES")
EOF
}
iptables_flush() {
iptables_init || return 1
iptables-restore <<-EOF || {
$(echo -e "$( iptables-save)" | grep -v 'NFS')
EOF
iptables_run "$RULES_FILTER" "filter" "-D" &>/dev/null
iptables_run "$RULES_NAT" "nat" "-D" &>/dev/null
}
return $?
}
iptables_restore() {
iptables_init || return 1
iptables-restore -n <<-EOF || {
$RULES_FILTER
$RULES_NAT
EOF
iptables_run "$RULES_FILTER" "filter" "-A"
[ "$external_access" = '1' ] && iptables_run "$RULES_NAT" "nat" "-A"
}
return $?
}
nfs_general() {
config_get external_access "$1" external_access '0'
}
nfs_share() {
[ -z "$1" ] && return 1
config_get enabled "$1" enabled
[ "$enabled" = '1' ] || return 1
config_get path "$1" path
[ -d "$path" ] || return 1
config_get clients "$1" clients
[ -z "$clients" ] && return 1
config_get permission "$1" permission '0'
case $permission in
1)
NFS_PERMISSION='no_root_squash'
;;
2)
NFS_PERMISSION='no_root_squash,fsid=0'
;;
*)
NFS_PERMISSION='all_squash'
;;
esac
config_get read_only "$1" read_only '0'
NFS_OPERATION="rw"
[ $read_only = '1' ] && NFS_OPERATION="ro"
NFS_INSECURE=""
config_get insecure "$1" insecure '1'
[ $insecure = '1' ] && NFS_INSECURE=",insecure"
[ -z "$NFS_SHARE_ALL" ] || {
FIND_NFS=$(echo -e "$NFS_SHARE_ALL"|grep -i "^$path ")
}
if [ -z "$FIND_NFS" ]; then
NFS_SHARE_ALL=$([ -z "$NFS_SHARE_ALL" ] || echo "$NFS_SHARE_ALL\n")"$path $clients($NFS_OPERATION,no_subtree_check,$NFS_PERMISSION,async$NFS_INSECURE)"
else
NFS_SHARE_ALL=$(echo -e "$NFS_SHARE_ALL"|grep -iv "^$path ")
NFS_SHARE_ALL=$([ -z "$NFS_SHARE_ALL" ] || echo "$NFS_SHARE_ALL\n")"$FIND_NFS $clients($NFS_OPERATION,no_subtree_check,$NFS_PERMISSION,async$NFS_INSECURE)"
fi
}
nfs_share_start() {
NFS_EXPORTS=$(cat /etc/exports)
if check_nfsd; then
if [ -z "$NFS_SHARE_ALL" ]; then
echo -e "$NFS_SHARE_ALL">/etc/exports
nfs_share_stop
return 1
else
[ "$(echo -e $NFS_EXPORTS)" = "$(echo -e $NFS_SHARE_ALL)" ] || {
echo -e "$NFS_SHARE_ALL">/etc/exports
/usr/sbin/exportfs -ar
}
fi
else
echo -e "$NFS_SHARE_ALL">/etc/exports
/etc/init.d/portmap start &>/dev/null
/etc/init.d/nfsd start &>/dev/null
fi
iptables_flush
iptables_restore
}
nfs_share_stop() {
iptables_flush
/etc/init.d/nfsd stop &>/dev/null
/etc/init.d/portmap stop &>/dev/null
}
get_mounted_nfs() {
[ -z "$MOUNTED_ALL" ] && {
MOUNTED_ALL=$(mount)
MOUNTED_NFS_ALL=$(echo -e "$MOUNTED_ALL"|grep "type\s\+nfs\s")
}
}
create_mount_dir() {
if [ -d "$1" ]; then
[ -z $(ls $"$1" 2>/dev/null) ] && return 0
return 1
else
mkdir "$1"
return 0
fi
}
nfs_mount() {
[ -z "$1" ] && return 1
config_get enabled "$1" enabled
[ "$enabled" = '1' ] || return 1
config_get host "$1" host
[ -z "$host" ] && return 1
config_get path "$1" path
[ -z "$path" ] && return 1
config_get mount_on "$1" mount_on
[ -z "$mount_on" ] && return 1
config_get read_only "$1" read_only '0'
MOUNT_OPERATION="rw"
[ $read_only = '1' ] && MOUNT_OPERATION="ro"
get_mounted_nfs
NFS_MOUNTING=$([ -z "$NFS_MOUNTING" ] || echo "$NFS_MOUNTING\n")"$host:$path"
NFS_MOUNT_MATCH=$(echo -e "$MOUNTED_NFS_ALL"|grep "^$host:$path")
if [ -z "$NFS_MOUNT_MATCH" ]; then
create_mount_dir "$mount_on" && mount -t nfs -o $MOUNT_OPERATION -o nolock "$host:$path" "$mount_on"
else
echo "$NFS_MOUNT_MATCH"|grep "$mount_on\s\+type\s\+nfs\s\+($MOUNT_OPERATION" 2>/dev/null && return 1
umount -fr "$mount_on" && mount -t nfs -o $MOUNT_OPERATION -o nolock "$host:$path" "$mount_on"
fi
}
nfs_mount_clean() {
MOUNTED_ALL=''
get_mounted_nfs
echo -e "$MOUNTED_NFS_ALL"|while read NFS_SHARED
do
echo -e "$NFS_MOUNTING"|grep -x "${NFS_SHARED% on *}" 2>/dev/null || {
NFS_SHARED_MOUNT="${NFS_SHARED##* on }"
NFS_SHARED_MOUNT="${NFS_SHARED_MOUNT%% type*}"
umount -fr "$NFS_SHARED_MOUNT" && rm -r "$NFS_SHARED_MOUNT"
}
done
}
config_cb() {
local cfg="$CONFIG_SECTION"
config_get configname "$cfg" TYPE
case "$configname" in
general)
nfs_general "$cfg"
;;
share)
nfs_share "$cfg"
;;
mount)
nfs_mount "$cfg"
;;
esac
}
start() {
config_load "$APP"
nfs_share_start
nfs_mount_clean
}
stop() {
nfs_mount_clean
nfs_share_stop
}
restart() {
start
}
firewall() {
config_load "$APP"
iptables_restore
}