[ClusterLabs] Notice: SLES11SP4 broke exportfs!
Ulrich Windl
Ulrich.Windl at rz.uni-regensburg.de
Fri Dec 11 18:27:28 UTC 2015
Hi!
After updating from SLES11SP3 (june version) to SLES11SP4 (todays version) exportfs fails to get the export status. I have message like this in syslog:
Dec 11 19:22:09 h04 crmd[11128]: notice: process_lrm_event: rksaph04-prm_nfs_c11_mnt_exp_monitor_0:93 [ /usr/lib/ocf/resource.d/heartbeat/exportfs: line 178: 4f838db1: value too great for base (error token is "4f838db1")\n ]
Why is such broken code released? Here's the diff:
--- /usr/lib/ocf/resource.d/heartbeat/exportfs 2015-03-11 07:00:04.000000000 +0100
+++ /tmp/exportfs 2015-10-14 21:13:39.000000000 +0200
@@ -46,7 +46,7 @@
<parameter name="clientspec" unique="0" required="1">
<longdesc lang="en">
The client specification allowing remote machines to mount the directory
-over NFS.
+(or directories) over NFS.
</longdesc>
<shortdesc lang="en">
Client ACL.
@@ -56,7 +56,8 @@
<parameter name="options" unique="0" required="0">
<longdesc lang="en">
-The options to pass to exportfs for the exported directory.
+The options to pass to exportfs for the exported directory
+or directories.
</longdesc>
<shortdesc lang="en">
Export options.
@@ -66,10 +67,11 @@
<parameter name="directory" unique="0" required="1">
<longdesc lang="en">
-The directory which you wish to export using NFS.
+The directory or directories to be exported using NFS. Multiple
+directories are separated by white space.
</longdesc>
<shortdesc lang="en">
-The directory to export.
+The directory or directories to export.
</shortdesc>
<content type="string" />
</parameter>
@@ -79,13 +81,17 @@
The fsid option to pass to exportfs. This can be a unique positive
integer, a UUID, or the special string "root" which is functionally
identical to numeric fsid of 0.
+If multiple directories are being exported, then they are
+assigned ids sequentially starting with this fsid (fsid, fsid+1,
+fsid+2, ...). Obviously, in that case the fsid must be an
+integer.
0 (root) identifies the export as the root of an NFSv4
pseudofilesystem -- avoid this setting unless you understand its
special status.
This value will override any fsid provided via the options parameter.
</longdesc>
<shortdesc lang="en">
-Unique fsid within cluster.
+Unique fsid within cluster or starting fsid for multiple exports.
</shortdesc>
<content type="string" />
</parameter>
@@ -165,18 +171,48 @@
!
}
+reset_fsid() {
+ CURRENT_FSID=$OCF_RESKEY_fsid
+}
+bump_fsid() {
+ let $((CURRENT_FSID++))
+}
+get_fsid() {
+ echo $CURRENT_FSID
+}
+
+# run a function on all directories
+forall() {
+ local func=$1
+ shift 1
+ local fast_exit=""
+ local dir rc=0
+ if [ "$2" = fast_exit ]; then
+ fast_exit=1
+ shift 1
+ fi
+ reset_fsid
+ for dir in $OCF_RESKEY_directory; do
+ $func $dir "$@"
+ rc=$(($rc | $?))
+ bump_fsid
+ [ "$fast_exit" ] && continue
+ [ $rc -ne 0 ] && return $rc
+ done
+ return $rc
+}
+
backup_rmtab() {
+ local dir=$1
local rmtab_backup
- if [ ${OCF_RESKEY_rmtab_backup} != "none" ]; then
- rmtab_backup="${OCF_RESKEY_directory}/${OCF_RESKEY_rmtab_backup}"
- grep ":${OCF_RESKEY_directory}:" /var/lib/nfs/rmtab > ${rmtab_backup}
- fi
+ rmtab_backup="$dir/${OCF_RESKEY_rmtab_backup}"
+ grep ":$dir:" /var/lib/nfs/rmtab > ${rmtab_backup}
}
restore_rmtab() {
+ local dir=$1
local rmtab_backup
- if [ ${OCF_RESKEY_rmtab_backup} != "none" ]; then
- rmtab_backup="${OCF_RESKEY_directory}/${OCF_RESKEY_rmtab_backup}"
+ rmtab_backup="$dir/${OCF_RESKEY_rmtab_backup}"
if [ -r ${rmtab_backup} ]; then
local tmpf=`mktemp`
sort -u ${rmtab_backup} /var/lib/nfs/rmtab > $tmpf &&
@@ -186,7 +222,6 @@
else
ocf_log warn "rmtab backup ${rmtab_backup} not found or not readable."
fi
- fi
}
exportfs_usage() {
@@ -195,86 +230,95 @@
END
}
+format_exports() {
+ # exportfs output wraps lines for long export directory names.
+ # We unwrap here with sed.
+ # We then do a literal match on the full line (grep -x -F)
+ exportfs |
+ sed -e '$! N; s/\n[[:space:]]\+/ /; t; s/[[:space:]]\+\([^[:space:]]\+\)\(\n\|$\)/ \1\2/g; P;D;'
+}
is_exported() {
local dir=$1
local spec=$2
- exportfs |
- sed -e '$! N; s/\n[[:space:]]\+/ /; t; s/[[:space:]]\+\([^[:space:]]\+\)\(\n\|$\)/ \1\2/g; P;D;' |
- grep -q -x -F "$dir $spec"
-}
-
-exportfs_monitor ()
-{
local rc
- # exportfs output wraps lines for long export directory names.
- # We unwrap here with sed.
- # We then do a literal match on the full line (grep -x -F)
- is_exported "${OCF_RESKEY_directory}" "${OCF_RESKEY_clientspec}"
+ format_exports | grep -q -x -F "$dir $spec"
rc=$?
-
- # on some platforms, exportfs may print "<world>" instead of
- # "*"
- if [ $rc -eq 1 -a "${OCF_RESKEY_clientspec}" = "*" ]; then
- is_exported "${OCF_RESKEY_directory}" "<world>"
+ if [ $rc -ne 0 -a "$spec" = "*" ]; then
+ # on some platforms, exportfs may print
+ # "<world>" instead of "*"
+ format_exports | grep -q -x -F "$dir <world>"
rc=$?
fi
-
-#Adapt grep status code to OCF return code
- case $rc in
- 0)
- ocf_log info "Directory ${OCF_RESKEY_directory} is exported to ${OCF_RESKEY_clientspec} (started)."
- # Backup the rmtab to ensure smooth NFS-over-TCP failover
- backup_rmtab
- return $OCF_SUCCESS
- ;;
- 1)
- ocf_log info "Directory ${OCF_RESKEY_directory} is not exported to ${OCF_RESKEY_clientspec} (stopped)."
- return $OCF_NOT_RUNNING;;
- *)
- ocf_log err "Unable to determine export status for ${OCF_RESKEY_directory}."
- return $OCF_ERR_GENERIC;;
- esac
+ # log something only for monitors
+ if [ $rc -ne 0 -a "$__OCF_ACTION" = "monitor" ]; then
+ local sev="info"
+ ocf_is_probe || sev="err"
+ ocf_log $sev "$dir not exported to $spec (stopped)."
+ fi
+ return $rc
}
-exportfs_start ()
+exportfs_monitor ()
{
- if exportfs_monitor; then
- ocf_log debug "${OCF_RESKEY_directory} already exported"
+ if forall is_exported "${OCF_RESKEY_clientspec}"; then
+ if [ ${OCF_RESKEY_rmtab_backup} != "none" ]; then
+ forall backup_rmtab
+ fi
return $OCF_SUCCESS
+ else
+ return $OCF_NOT_RUNNING
fi
-
- ocf_log info "Exporting file system ..."
+}
- if [ ${OCF_RESKEY_options} ]; then
- OPTIONS="${OCF_RESKEY_options}"
- OPTPREFIX=','
- fi
- if [ `echo ${OPTIONS} | grep fsid` ]; then
- #replace fsid provided in options list with one provided in fsid param.
- OPTIONS=`echo ${OPTIONS} | sed "s/fsid=[0-9]\+/fsid=${OCF_RESKEY_fsid}/g"`
+export_one() {
+ local dir=$1
+ local opts sep
+ sep=""
+ if [ -n "$OCF_RESKEY_options" ]; then
+ opts="$OCF_RESKEY_options"
+ sep=","
+ fi
+ if echo "$opts" | grep fsid >/dev/null; then
+ #replace fsid in options list
+ opts=`echo "$opts" | sed "s/fsid=[0-9]\+/fsid=$(get_fsid)/g"`
else
#tack the fsid option onto our options list.
- OPTIONS="${OPTIONS}${OPTPREFIX}fsid=${OCF_RESKEY_fsid}"
+ opts="${opts}${sep}fsid=$(get_fsid)"
fi
- OPTIONS="-o ${OPTIONS}"
+ opts="-o $opts"
- ocf_run exportfs -v ${OPTIONS} ${OCF_RESKEY_clientspec}:${OCF_RESKEY_directory} || exit $OCF_ERR_GENERIC
-
- # Restore the rmtab to ensure smooth NFS-over-TCP failover
- restore_rmtab
+ # if any of directories fails to export we can exit
+ # immediately
+ ocf_run exportfs -v $opts "${OCF_RESKEY_clientspec}:$dir" ||
+ exit $OCF_ERR_GENERIC
- ocf_log info "File system exported"
+ ocf_log info "directory $dir exported"
return $OCF_SUCCESS
}
+exportfs_start ()
+{
+ if exportfs_monitor; then
+ ocf_log debug "already exported"
+ return $OCF_SUCCESS
+ fi
+ ocf_log info "Exporting file system(s) ..."
+ forall export_one
+
+ # Restore the rmtab to ensure smooth NFS-over-TCP failover
+ if [ ${OCF_RESKEY_rmtab_backup} != "none" ]; then
+ forall restore_rmtab
+ fi
+}
unlock_fs() {
+ local dir=$1
local unlockfile
unlockfile=/proc/fs/nfsd/unlock_filesystem
if [ -w ${unlockfile} ]; then
- echo "${OCF_RESKEY_directory}" > ${unlockfile}
- ocf_log info "Unlocked NFS export ${OCF_RESKEY_directory}"
+ echo "$dir" > ${unlockfile}
+ ocf_log info "Unlocked NFS export $dir"
else
- ocf_log warn "Unable to unlock NFS export ${OCF_RESKEY_directory}, ${unlockfile} not found or not writable"
+ ocf_log warn "Unable to unlock NFS export $dir, ${unlockfile} not found or not writable"
fi
}
wait_for_leasetime() {
@@ -292,10 +336,11 @@
cleanup_export_cache() {
# see if the cache is blocking unexport
local contentfile=/proc/net/rpc/nfsd.export/content
- local fsid_re="fsid=$OCF_RESKEY_fsid,"
+ local fsid_re
local i=1
+ fsid_re="fsid=(echo `forall get_fsid`|sed 's/ /|/g'),"
while :; do
- fgrep -q "$fsid_re" $contentfile ||
+ grep -E -q "$fsid_re" $contentfile ||
break
ocf_log info "Cleanup export cache ... (try $i)"
ocf_run exportfs -f
@@ -303,24 +348,32 @@
let i=$i+1
done
}
+unexport_one() {
+ local dir=$1
+ ocf_run exportfs -v -u ${OCF_RESKEY_clientspec}:$dir
+}
exportfs_stop ()
{
+ local rc
+
exportfs_monitor
if [ $? -eq $OCF_NOT_RUNNING ]; then
- ocf_log debug "${OCF_RESKEY_directory} not exported"
+ ocf_log debug "not exported"
return $OCF_SUCCESS
fi
ocf_log info "Un-exporting file system ..."
# Backup the rmtab to ensure smooth NFS-over-TCP failover
- backup_rmtab
+ if [ ${OCF_RESKEY_rmtab_backup} != "none" ]; then
+ forall backup_rmtab
+ fi
- ocf_run exportfs -v -u ${OCF_RESKEY_clientspec}:${OCF_RESKEY_directory}
+ forall unexport_one
rc=$?
if ocf_is_true ${OCF_RESKEY_unlock_on_stop}; then
- unlock_fs
+ forall unlock_fs
fi
if ocf_is_true ${OCF_RESKEY_wait_for_leasetime_on_stop}; then
@@ -329,18 +382,30 @@
if [ $rc -eq 0 ]; then
cleanup_export_cache
- ocf_log info "Un-exported file system"
+ ocf_log info "Un-exported file system(s)"
return $OCF_SUCCESS
else
- ocf_log err "Failed to un-export file system"
- exit $OCF_ERR_GENERIC
+ ocf_log err "Failed to un-export file system(s)"
+ return $OCF_ERR_GENERIC
fi
}
+testdir() {
+ if [ ! -d $1 ]; then
+ ocf_is_probe ||
+ ocf_log err "$1 does not exist or is not a directory"
+ return 1
+ fi
+ return 0
+}
exportfs_validate_all ()
{
- if [ ! -d $OCF_RESKEY_directory ]; then
- ocf_log err "$OCF_RESKEY_directory does not exist or is not a directory"
+ if [ `echo "$OCF_RESKEY_directory" | wc -w` -gt 1 ] &&
+ ! ocf_is_decimal "$OCF_RESKEY_fsid"; then
+ ocf_log err "use integer fsid when exporting multiple directories"
+ return $OCF_ERR_CONFIGURED
+ fi
+ if ! forall testdir; then
return $OCF_ERR_INSTALLED
fi
}
Obviously too much diff for a stable version!
Regards,
Ulrich
More information about the Users
mailing list