[Debian-ha-commits] [cluster-glue] 38/73: Imported Upstream version 1.0.10+hg2722
Richard Winters
devrik-guest at moszumanska.debian.org
Sat Apr 18 20:24:35 UTC 2015
This is an automated email from the git hooks/post-receive script.
devrik-guest pushed a commit to branch master
in repository cluster-glue.
commit cbf69e106c6f593ff52f1a21ce7a46466cc9e6d8
Author: Richard B Winters <rik at mmogp.com>
Date: Sat Apr 18 07:48:51 2015 -0400
Imported Upstream version 1.0.10+hg2722
---
.hg_archival.txt | 2 +-
.hgtags | 1 +
ChangeLog | 33 ++
cluster-glue-fedora.spec | 12 +-
cluster-glue-suse.spec | 4 +-
configure.ac | 34 +-
hb_report/hb_report.in | 95 ++++--
hb_report/utillib.sh | 132 ++++----
include/clplumbing/cl_uuid.h | 2 +-
include/clplumbing/ipc.h | 2 +-
include/compress.h | 4 +-
lib/clplumbing/GSource.c | 5 +-
lib/clplumbing/Gmain_timeout.c | 198 -----------
lib/clplumbing/Makefile.am | 1 -
lib/clplumbing/cl_compress.c | 17 +-
lib/clplumbing/cl_msg.c | 105 ++----
lib/clplumbing/cl_plugin.c | 2 +-
lib/clplumbing/ipcsocket.c | 613 ++++++++++++++---------------------
lib/clplumbing/ipctest.c | 18 +-
lib/clplumbing/ocf_ipc.c | 287 +++++++---------
lib/plugins/Makefile.am | 2 +-
lib/plugins/compress/Makefile.am | 52 +++
lib/plugins/compress/bz2.c | 142 ++++++++
lib/plugins/compress/zlib.c | 135 ++++++++
lib/plugins/stonith/external/libvirt | 8 +-
lib/plugins/stonith/external/vcenter | 30 +-
lib/plugins/stonith/rhcs.c | 43 ++-
lib/stonith/Makefile.am | 2 +-
lib/stonith/ha_log.sh | 16 +-
lib/stonith/sbd-common.c | 253 +++++++++------
lib/stonith/sbd-md.c | 318 +++++++++---------
lib/stonith/sbd.h | 79 +++--
logd/logd.in | 8 +-
lrm/lrmd/lrmd.c | 32 +-
lrm/lrmd/lrmd_fdecl.h | 1 +
lrm/test/Makefile.am | 2 +-
lrm/test/lrmregtest-heartbeat.in | 17 -
lrm/test/lrmregtest-lsb | 54 +++
lrm/test/lrmregtest-lsb.in | 12 -
lrm/test/regression.sh.in | 20 +-
lrm/test/testcases/rscexec | 15 -
lrm/test/testcases/rscexec.exp | 58 ----
lrm/test/testcases/rscmgmt | 7 +-
lrm/test/testcases/rscmgmt.exp | 15 +-
lrm/test/testcases/xmllint.sh | 2 +-
45 files changed, 1518 insertions(+), 1372 deletions(-)
diff --git a/.hg_archival.txt b/.hg_archival.txt
index 0ed25bf..0a916f4 100644
--- a/.hg_archival.txt
+++ b/.hg_archival.txt
@@ -1,2 +1,2 @@
repo: e3ffdd7ae81c596b2be7e1e110d2c1255161340e
-node: bce0f5e5e6abee3655eec494e63d679f24203c51
+node: 1f36e9cdcc13369e9cb117b46c0f23b9d1757dc4
diff --git a/.hgtags b/.hgtags
index 11b8031..422828a 100644
--- a/.hgtags
+++ b/.hgtags
@@ -62,3 +62,4 @@ f6c2cd2593f365f984ce051db61466738ac05dcd Beta-0.4.9f
5740338816e1ff07d0e37f36214f442e183984d7 glue-1.0.8-rc1
c69dc6ace936f501776df92dab3d611c2405f69e glue-1.0.8
0a08a469fdc8a0db1875369497bc83c0523ceb21 glue-1.0.9
+12055ca2b025ab250a544701edaa1f5aaf63aef1 glue-1.0.10
diff --git a/ChangeLog b/ChangeLog
index f7b60b8..579143d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,36 @@
+* Mon Jul 16 2012 Dejan Muhamedagic <dejan at suse.de>, Lars Ellenberg <lars.ellenberg at linbit.com>, and many others
+- stable release 1.0.10
+- clplumbing: ipc: fix message size checks (bnc#752231)
+- clplumbing: load bz2 compression module by default
+- clplumbing: cl_msg: try compressing message before rejecting it
+ as too big
+- clplumbing: cl_msg: don't use traditional compression by default
+- clplumbing: cl_msg: increase compression threshold
+- clplumbing: fix memleak for Gmain_timeout
+- LRM: lrmd: add basic authentication (lf#2547)
+- LRM: lrmd: use the resource timeout as an override to the
+ default dbus timeout for upstart RA
+- LRM: lrmd: if set, get max-children from the LRMD_MAX_CHILDREN
+ environment var
+- stonith: add CRM stonith resource name to log messages (bnc#728579)
+- stonith: adjust timeouts in the meta-data template (bnc#733337)
+- stonith: external/vcenter: return list of configured hosts on
+ gethosts
+- stonith: external/libvirt: add more search strings for domain
+ start and stop
+- stonith: rhcs: pass the action via stdin too
+- stonith: rhcs: avoid false error if parameter isn't set
+- logd: remove runlevel 4 from the LSB info section in the logd
+ init script (bnc#744120)
+- logd: add try-restart action to the logd init script
+- sbd: Use async IO for disk reads to increase resilience against
+ hung IO (bnc#738295)
+- sbd: Handle IO errors during slot allocation properly (bnc#753559)
+- sbd: Debug mode added (bnc#753559, bnc#738295)
+- hb_report: improve performance
+- hb_report: get corosync blackbox records if available
+- hb_report: add node time information
+
* Mon Nov 28 2011 Dejan Muhamedagic <dejan at suse.de>, Lars Ellenberg <lars.ellenberg at linbit.com>, and many others
- stable release 1.0.9
- stonith: external/ipmi: add missing double quote
diff --git a/cluster-glue-fedora.spec b/cluster-glue-fedora.spec
index 42a25a5..a34316e 100644
--- a/cluster-glue-fedora.spec
+++ b/cluster-glue-fedora.spec
@@ -15,7 +15,7 @@
Name: cluster-glue
Summary: Reusable cluster components
-Version: 1.0.9
+Version: 1.0.10
Release: 1%{?dist}
License: GPLv2+ and LGPLv2+
Url: http://www.linux-ha.org/wiki/Cluster_Glue
@@ -37,7 +37,7 @@ BuildRoot: %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX)
# Build dependencies
BuildRequires: automake autoconf libtool pkgconfig which
-BuildRequires: bzip2-devel glib2-devel python-devel libxml2-devel
+BuildRequires: bzip2-devel glib2-devel python-devel libxml2-devel libaio-devel
BuildRequires: OpenIPMI-devel openssl-devel
BuildRequires: libxslt docbook-dtds docbook-style-xsl
BuildRequires: help2man
@@ -53,10 +53,10 @@ BuildRequires: net-snmp-devel >= 5.4
BuildRequires: gcc-c++
%endif
-%if 0%{?fedora} < 12
-BuildRequires: e2fsprogs-devel
-%else
+%if 0%{?fedora} > 11 || 0%{?centos} > 5 || 0%{?rhel} > 5
BuildRequires: libuuid-devel
+%else
+BuildRequires: e2fsprogs-devel
%endif
%prep
@@ -129,10 +129,12 @@ standards, and an interface to common STONITH devices.
%dir %{_libdir}/heartbeat/plugins
%dir %{_libdir}/heartbeat/plugins/RAExec
%dir %{_libdir}/heartbeat/plugins/InterfaceMgr
+%dir %{_libdir}/heartbeat/plugins/compress
%{_libdir}/heartbeat/lrmd
%{_libdir}/heartbeat/ha_logd
%{_libdir}/heartbeat/plugins/RAExec/*.so
%{_libdir}/heartbeat/plugins/InterfaceMgr/*.so
+%{_libdir}/heartbeat/plugins/compress/*.so
%dir %{_libdir}/stonith
%dir %{_libdir}/stonith/plugins
%dir %{_libdir}/stonith/plugins/stonith2
diff --git a/cluster-glue-suse.spec b/cluster-glue-suse.spec
index bb81acd..4eba31a 100644
--- a/cluster-glue-suse.spec
+++ b/cluster-glue-suse.spec
@@ -29,7 +29,7 @@
Name: cluster-glue
Summary: Reusable cluster components
-Version: 1.0.9
+Version: 1.0.10
Release: 1%{?dist}
License: GPL v2 or later; LGPL v2.1 or later
Url: http://www.linux-ha.org/wiki/Cluster_Glue
@@ -191,6 +191,7 @@ fi
%dir %{_libdir}/heartbeat/plugins
%dir %{_libdir}/heartbeat/plugins/RAExec
%dir %{_libdir}/heartbeat/plugins/InterfaceMgr
+%dir %{_libdir}/heartbeat/plugins/compress
%dir %{_libdir}/stonith
%dir %{_libdir}/stonith/plugins
@@ -228,6 +229,7 @@ fi
%{_libdir}/heartbeat/plugins/RAExec/*.so
%{_libdir}/heartbeat/plugins/InterfaceMgr/*.so
+%{_libdir}/heartbeat/plugins/compress/*.so
%{_libdir}/stonith/plugins/external
%{_libdir}/stonith/plugins/stonith2/*.so
diff --git a/configure.ac b/configure.ac
index 6cf7a58..41cc1cc 100644
--- a/configure.ac
+++ b/configure.ac
@@ -19,7 +19,7 @@ dnl checks for compiler characteristics
dnl checks for library functions
dnl checks for system services
-AC_INIT(cluster-glue, 1.0.9, linux-ha-dev at lists.linux-ha.org)
+AC_INIT(cluster-glue, 1.0.10, linux-ha-dev at lists.linux-ha.org)
FEATURES=""
HB_PKG=heartbeat
@@ -703,6 +703,11 @@ if test "$ac_cv_header_libxml_xpath_h" != "yes"; then
AC_MSG_ERROR(The libxml developement headers were not found)
fi
+AC_CHECK_HEADERS(libaio.h)
+if test "$ac_cv_header_libaio_h" != "yes"; then
+ AC_MSG_ERROR(The libaio developement headers were not found)
+fi
+
dnl Check syslog.h for 'facilitynames' table
dnl
AC_CACHE_CHECK([for facilitynames in syslog.h],ac_cv_HAVE_SYSLOG_FACILITYNAMES,[
@@ -1090,16 +1095,28 @@ AM_CONDITIONAL(USE_OPENHPI, test "$ac_cv_header_openhpi_SaHpi_h" = yes && pkg-co
AM_CONDITIONAL(IPMILAN_BUILD, test "X$enable_ipmilan" = "Xyes")
dnl ========================================================================
-dnl BZ2
+dnl ZLIB and BZ2
dnl ========================================================================
-AC_CHECK_HEADERS(bzlib.h)
-AC_CHECK_LIB(bz2, BZ2_bzBuffToBuffCompress)
-
-if test x$ac_cv_lib_bz2_BZ2_bzBuffToBuffCompress != xyes ; then
- AC_MSG_ERROR(BZ2 libraries not found)
+dnl check if header file and lib are there for zlib
+zlib_installed="yes"
+AC_CHECK_HEADERS(zlib.h, , [zlib_installed="no"],)
+AC_CHECK_LIB(z, compress , , [zlib_installed="no"])
+AM_CONDITIONAL(BUILD_ZLIB_COMPRESS_MODULE, test "x${zlib_installed}" = "xyes")
+if test "x${zlib_installed}" = "xno"; then
+ FatalMissingThing "zlib" \
+ "The zlib library is missing"
fi
+bz2_installed="yes"
+AC_CHECK_HEADERS(bzlib.h, , [bz2_installed="no"],)
+AC_CHECK_LIB(bz2, BZ2_bzBuffToBuffCompress , , [bz2_installed="no"])
+AM_CONDITIONAL(BUILD_BZ2_COMPRESS_MODULE, test "x${bz2_installed}" = "xyes")
+
+#if test x$ac_cv_lib_bz2_BZ2_bzBuffToBuffCompress != xyes ; then
+# AC_MSG_ERROR(BZ2 libraries not found)
+#fi
+
if test x$ac_cv_header_bzlib_h != xyes; then
AC_MSG_ERROR(BZ2 Development headers not found)
fi
@@ -1324,6 +1341,7 @@ lib/Makefile \
lib/lrm/Makefile \
lib/plugins/Makefile \
lib/plugins/InterfaceMgr/Makefile \
+ lib/plugins/compress/Makefile \
lib/plugins/lrm/Makefile \
lib/plugins/lrm/dbus/Makefile \
lib/plugins/stonith/Makefile \
@@ -1341,8 +1359,6 @@ lrm/Makefile \
lrm/test/Makefile \
lrm/test/regression.sh \
lrm/test/lrmregtest \
- lrm/test/lrmregtest-lsb \
- lrm/test/lrmregtest-heartbeat \
lrm/test/LRMBasicSanityCheck \
lrm/test/testcases/Makefile \
logd/Makefile \
diff --git a/hb_report/hb_report.in b/hb_report/hb_report.in
index 32947d6..f5745cd 100755
--- a/hb_report/hb_report.in
+++ b/hb_report/hb_report.in
@@ -54,6 +54,8 @@ stonith crmd.*te_fence_node.*Exec|stonith-ng.*log_oper.*reboot|stonithd.*(reque
start_stop Configuration.validated..Starting.heartbeat|Corosync.Cluster.Engine|Executive.Service.RELEASE|crm_shutdown:.Requesting.shutdown|pcmk_shutdown:.Shutdown.complete
"
+init_tmpfiles
+
#
# the instance where user runs hb_report is the master
# the others are slaves
@@ -271,6 +273,7 @@ is_our_log() {
# hasn't been changed)
#
arch_logs() {
+ local next_log
local logf=$1
local from_time=$2
local to_time=$3
@@ -296,24 +299,27 @@ arch_logs() {
#
# print part of the log
#
-drop_tmp_file() {
- [ -z "$tmp" ] || rm -f "$tmp"
-}
print_log() {
local cat=`find_decompressor $1`
$cat $1
}
print_logseg() {
+ if test -x $HA_NOARCHBIN/print_logseg; then
+ $HA_NOARCHBIN/print_logseg "$1" "$2" "$3"
+ return
+ fi
+
local logf=$1
local from_time=$2
local to_time=$3
+ local tmp sourcef
# uncompress to a temp file (if necessary)
local cat=`find_decompressor $logf`
if [ "$cat" != "cat" ]; then
tmp=`mktemp`
+ add_tmpfiles $tmp
$cat $logf > $tmp
- trap drop_tmp_file 0
sourcef=$tmp
else
sourcef=$logf
@@ -340,8 +346,6 @@ print_logseg() {
fi
dumplog $sourcef $FROM_LINE $TO_LINE
debug "including segment [$FROM_LINE-$TO_LINE] from $logf"
- drop_tmp_file
- trap "" 0
}
#
# print some log info (important for crm history)
@@ -519,6 +523,7 @@ findsshuser() {
# the usual stuff
#
getbacktraces() {
+ local f bf flist
flist=$(
for f in `find_files "$CORES_DIRS" $1 $2`; do
bf=`basename $f`
@@ -539,6 +544,7 @@ pe2dot() {
)
}
getpeinputs() {
+ local pe_dir flist
local f
debug "looking for PE files in $HA_VARLIB/pengine, `dirname $HA_VARLIB`/pengine"
for pe_dir in $HA_VARLIB/pengine `dirname $HA_VARLIB`/pengine
@@ -563,13 +569,25 @@ getpeinputs() {
done
}
touch_DC_if_dc() {
- #dc=`crmadmin -D 2>/dev/null | awk '{print $NF}'`
- dc=`crm_mon -1 2>/dev/null | awk '/Current DC/ {print $3}'`
+ local dc
+ dc=`crmadmin -D 2>/dev/null | awk '{print $NF}'`
if [ "$WE" = "$dc" ]; then
touch $1/DC
fi
}
+corosync_blackbox() {
+ local from_time=$1
+ local to_time=$2
+ local outf=$3
+ local inpf
+ inpf=`find_files /var/lib/corosync $from_time $to_time | grep -w fdata`
+ if [ -f "$inpf" ]; then
+ corosync-fplay > $outf
+ touch -r $inpf $outf
+ fi
+}
getconfigurations() {
+ local conf
local dest=$1
for conf in $CONFIGURATIONS; do
if [ -f $conf ]; then
@@ -629,6 +647,10 @@ sys_stats() {
done
set +x
}
+time_status() {
+ date
+ ntpdc -pn
+}
dlm_dump() {
if which dlm_tool >/dev/null 2>&1 ; then
echo NOTICE - Lockspace overview:
@@ -648,6 +670,7 @@ dlm_dump() {
# replace sensitive info with '****'
#
sanitize() {
+ local f rc
for f in $1/$B_CONF; do
[ -f "$f" ] && sanitize_one $f
done
@@ -711,12 +734,13 @@ checkpermissions() {
done
}
checklogs() {
+ local logs pattfile l n
logs=$(find $1 -name $HALOG_F;
for l in $EXTRA_LOGS; do find $1/* -name `basename $l`; done)
[ "$logs" ] || return
- trap '[ -z "$pattfile" ] || rm -f "$pattfile"' 0
pattfile=`mktemp` ||
fatal "cannot create temporary files"
+ add_tmpfiles $pattfile
for p in $LOG_PATTERNS; do
echo "$p"
done > $pattfile
@@ -725,14 +749,13 @@ checklogs() {
for n in $NODES; do
cat $logs | grep -f $pattfile
done
- rm -f $pattfile
- trap "" 0
}
#
# check if files have same content in the cluster
#
cibdiff() {
+ local d1 d2
d1=`dirname $1`
d2=`dirname $2`
if [ -f $d1/RUNNING -a -f $d2/RUNNING ] ||
@@ -768,6 +791,7 @@ diffcheck() {
esac
}
analyze_one() {
+ local rc node0 n
rc=0
node0=""
for n in $NODES; do
@@ -781,6 +805,7 @@ analyze_one() {
return $rc
}
analyze() {
+ local f flist
flist="$HOSTCACHE $MEMBERSHIP_F $CIB_F $CRM_MON_F $B_CONF logd.cf $SYSINFO_F"
for f in $flist; do
printf "Diff $f... "
@@ -802,6 +827,7 @@ analyze() {
checklogs $1
}
events_all() {
+ local Epatt title p
Epatt=`echo "$EVENT_PATTERNS" |
while read title p; do [ -n "$p" ] && echo -n "|$p"; done |
sed 's/.//'
@@ -809,6 +835,7 @@ events_all() {
grep -E "$Epatt" $1
}
events() {
+ local destdir n
destdir=$1
if [ -f $destdir/$HALOG_F ]; then
events_all $destdir/$HALOG_F > $destdir/events.txt
@@ -831,6 +858,7 @@ events() {
# (network delay, machine load)
#
combine_logs() {
+ local destdir
destdir=$1
test $NODECNT -gt 1 ||
return
@@ -883,6 +911,7 @@ EOF
fi
}
edittemplate() {
+ local ec
if ec=`pickfirst $EDITOR vim vi emacs nano`; then
$ec $1
else
@@ -904,6 +933,7 @@ pickcompress() {
}
# get the right part of the log
getlog() {
+ local getstampproc cnt
local outf
if [ "$HA_LOG" ]; then # log provided by the user?
@@ -951,17 +981,21 @@ getlog() {
# get all other info (config, stats, etc)
#
collect_info() {
+ local getstampproc l
+ sys_info > $WORKDIR/$SYSINFO_F 2>&1 &
+ sys_stats > $WORKDIR/$SYSSTATS_F 2>&1 &
getconfig $WORKDIR
- getpeinputs $FROM_TIME $TO_TIME $WORKDIR
+ getpeinputs $FROM_TIME $TO_TIME $WORKDIR &
+ crmconfig $WORKDIR &
+ touch_DC_if_dc $WORKDIR &
getbacktraces $FROM_TIME $TO_TIME $WORKDIR/$BT_F
getconfigurations $WORKDIR
- touch_DC_if_dc $WORKDIR
- sanitize $WORKDIR
- crmconfig $WORKDIR
check_perms > $WORKDIR/$PERMISSIONS_F 2>&1
- sys_info > $WORKDIR/$SYSINFO_F 2>&1
dlm_dump > $WORKDIR/$DLM_DUMP_F 2>&1
- sys_stats > $WORKDIR/$SYSSTATS_F 2>&1
+ time_status > $WORKDIR/$TIME_F 2>&1
+ corosync_blackbox $FROM_TIME $TO_TIME $WORKDIR/$COROSYNC_RECORDER_F
+ wait
+ sanitize $WORKDIR
for l in $EXTRA_LOGS; do
[ "$NO_str2time" ] && break
@@ -1005,7 +1039,7 @@ fi
WE=`uname -n` # who am i?
tmpdir=`mktemp -t -d .hb_report.workdir.XXXXXX`
-trap "rm -r $tmpdir" EXIT
+add_tmpfiles $tmpdir
WORKDIR=$tmpdir
#
@@ -1071,7 +1105,13 @@ if is_collector; then
. $WORKDIR/.env
fi
-[ $VERBOSITY -gt 1 ] && set -x
+[ $VERBOSITY -gt 1 ] && {
+ is_collector || {
+ info "high debug level, please read debug.out"
+ }
+ exec 2>>$WORKDIR/debug.out
+ set -x
+}
# allow user to enforce the cluster type
# if not, then it is found out on _all_ nodes
@@ -1159,7 +1199,8 @@ BT_F=backtraces.txt
SYSINFO_F=sysinfo.txt
SYSSTATS_F=sysstats.txt
DLM_DUMP_F=dlm_dump.txt
-export ANALYSIS_F DESCRIPTION_F HALOG_F BT_F SYSINFO_F SYSSTATS_F DLM_DUMP_F
+TIME_F=time.txt
+export ANALYSIS_F DESCRIPTION_F HALOG_F BT_F SYSINFO_F SYSSTATS_F DLM_DUMP_F TIME_F
CRM_MON_F=crm_mon.txt
MEMBERSHIP_F=members.txt
HB_UUID_F=hb_uuid.txt
@@ -1168,8 +1209,10 @@ CRM_VERIFY_F=crm_verify.txt
PERMISSIONS_F=permissions.txt
CIB_F=cib.xml
CIB_TXT_F=cib.txt
+COROSYNC_RECORDER_F=fdata.txt
export CRM_MON_F MEMBERSHIP_F CRM_VERIFY_F CIB_F CIB_TXT_F HB_UUID_F PERMISSIONS_F
-CONFIGURATIONS="/etc/drbd.conf /etc/drbd.d"
+export COROSYNC_RECORDER_F
+CONFIGURATIONS="/etc/drbd.conf /etc/drbd.d /etc/booth/booth.conf"
export CONFIGURATIONS
# this only on master
@@ -1196,11 +1239,6 @@ if is_collector && [ "$HA_LOGFACILITY" ]; then
sleep 1
fi
-if is_collector && [ $VERBOSITY -gt 1 ]; then
- info "the debug information for node $WE is in $WE/debug.out"
- exec 2>>debug.out
-fi
-
#
# part 4: find the logs and cut out the segment for the period
#
@@ -1232,8 +1270,8 @@ if is_collector; then
(cd $WORKDIR/.. && tar cf - $WE)
else
wait $SLAVEPIDS
- analyze $WORKDIR > $WORKDIR/$ANALYSIS_F
- events $WORKDIR
+ analyze $WORKDIR > $WORKDIR/$ANALYSIS_F &
+ events $WORKDIR &
mktemplate > $WORKDIR/$DESCRIPTION_F
[ "$NO_DESCRIPTION" ] || {
echo press enter to edit the problem description...
@@ -1242,6 +1280,7 @@ else
}
test -f $WORKDIR/$HALOG_F ||
combine_logs $WORKDIR
+ wait
if [ "$COMPRESS" = "1" ]; then
pickcompress
(cd $WORKDIR/.. && tar cf - $DEST) | $COMPRESS_PROG > $DESTDIR/$DEST.tar$COMPRESS_EXT
diff --git a/hb_report/utillib.sh b/hb_report/utillib.sh
index 2ac569d..1f0d745 100644
--- a/hb_report/utillib.sh
+++ b/hb_report/utillib.sh
@@ -35,6 +35,7 @@ get_cluster_type() {
# find out which membership tool is installed
#
echo_membership_tool() {
+ local f membership_tools
membership_tools="ccm_tool crm_node"
for f in $membership_tools; do
which $f 2>/dev/null && break
@@ -77,6 +78,7 @@ get_logd_logvars() {
HA_DEBUGFILE=`logd_getcfvar debugfile`
}
findlogdcf() {
+ local f
for f in \
`test -x $HA_BIN/ha_logd &&
which strings > /dev/null 2>&1 &&
@@ -96,6 +98,7 @@ findlogdcf() {
# logging
#
syslogmsg() {
+ local severity logtag
severity=$1
shift 1
logtag=""
@@ -107,6 +110,7 @@ syslogmsg() {
# find log destination
#
findmsg() {
+ local d syslogdirs favourites mark log
# this is tricky, we try a few directories
syslogdirs="/var/log /var/logs /var/syslog /var/adm
/var/log/ha /var/log/cluster /var/log/pacemaker
@@ -151,10 +155,12 @@ getstamp_legacy() {
awk '{print $2}' | sed 's/_/ /'
}
linetime() {
+ local l
l=`tail -n +$2 $1 | head -1 | $getstampproc`
str2time "$l"
}
find_getstampproc() {
+ local t l func trycnt
t=0 l="" func=""
trycnt=10
while [ $trycnt -gt 0 ] && read l; do
@@ -188,6 +194,7 @@ findln_by_time() {
local tm=$2
local first=1
local last=`wc -l < $logf`
+ local tmid mid trycnt
while [ $first -le $last ]; do
mid=$((($last+$first)/2))
trycnt=10
@@ -237,17 +244,14 @@ isnumber() {
echo "$*" | grep -qs '^[0-9][0-9]*$'
}
touchfile() {
+ local t
t=`mktemp` &&
perl -e "\$file=\"$t\"; \$tm=$1;" -e 'utime $tm, $tm, $file;' &&
echo $t
}
-find_files_clean() {
- [ -z "$to_stamp" ] || rm -f "$to_stamp"
- to_stamp=""
- [ -z "$from_stamp" ] || rm -f "$from_stamp"
- from_stamp=""
-}
find_files() {
+ local dirs from_time to_time
+ local from_stamp to_stamp findexp
dirs=$1
from_time=$2
to_time=$3
@@ -255,24 +259,21 @@ find_files() {
warning "sorry, can't find files based on time if you don't supply time"
return
}
- trap find_files_clean 0
if ! from_stamp=`touchfile $from_time`; then
- warning "sorry, can't create temporary file for find_files"
+ warning "can't create temporary files"
return
fi
+ add_tmpfiles $from_stamp
findexp="-newer $from_stamp"
if isnumber "$to_time" && [ "$to_time" -gt 0 ]; then
if ! to_stamp=`touchfile $to_time`; then
- warning "sorry, can't create temporary file for" \
- "find_files"
- find_files_clean
+ warning "can't create temporary files"
return
fi
+ add_tmpfiles $to_stamp
findexp="$findexp ! -newer $to_stamp"
fi
find $dirs -type f $findexp
- find_files_clean
- trap "" 0
}
#
@@ -301,6 +302,7 @@ chk_id() {
return 1
}
check_perms() {
+ local f p uid gid n_uid n_gid
essential_files |
while read type f p uid gid; do
[ -$type $f ] || {
@@ -331,6 +333,7 @@ EOF
}
MYBINARIES="crmd|pengine|lrmd|attrd|cib|mgmtd|stonithd|corosync|libplumb|libpils"
listpkg_zypper() {
+ local bins
local binary=$1 core=$2
gdb $binary $core </dev/null 2>&1 |
awk -v bins="$MYBINARIES" '
@@ -345,6 +348,7 @@ fetchpkg_zypper() {
}
find_pkgmgr() {
local binary=$1 core=$2
+ local regex pkg_mgr
pkg_mgr_list |
while read regex pkg_mgr; do
if gdb $binary $core </dev/null 2>&1 |
@@ -370,6 +374,7 @@ get_debuginfo() {
fetchpkg_$pkg_mgr $pkgs
}
findbinary() {
+ local random_binary binary fullpath
random_binary=`which cat 2>/dev/null` # suppose we are lucky
binary=`gdb $random_binary $1 < /dev/null 2>/dev/null |
grep 'Core was generated' | awk '{print $5}' |
@@ -407,6 +412,7 @@ findbinary() {
fi
}
getbt() {
+ local corefile absbinpath
which gdb > /dev/null 2>&1 || {
warning "please install gdb to get backtraces"
return
@@ -427,13 +433,13 @@ getbt() {
# heartbeat configuration/status
#
iscrmrunning() {
+ local pid maxwait
ps -ef | grep -qs [c]rmd || return 1
- #crmadmin -D >/dev/null 2>&1 &
- crm_mon -1 >/dev/null 2>&1 &
+ crmadmin -D >/dev/null 2>&1 &
pid=$!
- maxwait=10
+ maxwait=100
while kill -0 $pid 2>/dev/null && [ $maxwait -gt 0 ]; do
- sleep 1
+ sleep 0.1
maxwait=$(($maxwait-1))
done
if kill -0 $pid 2>/dev/null; then
@@ -500,6 +506,7 @@ get_live_nodes() {
# this is not proper xml parsing, but it will work under the
# circumstances
is_sensitive_xml() {
+ local patt epatt
epatt=""
for patt in $SANITIZE; do
epatt="$epatt|$patt"
@@ -508,6 +515,7 @@ is_sensitive_xml() {
egrep -qs "name=\"$epatt\""
}
test_sensitive_one() {
+ local file compress decompress
file=$1
compress=""
echo $file | grep -qs 'gz$' && compress=gzip
@@ -521,6 +529,7 @@ test_sensitive_one() {
$decompress < $file | is_sensitive_xml
}
sanitize_xml_attrs() {
+ local patt
sed $(
for patt in $SANITIZE; do
echo "-e /name=\"$patt\"/s/value=\"[^\"]*\"/value=\"****\"/"
@@ -533,13 +542,8 @@ sanitize_hacf() {
{print}
'
}
-sanitize_one_clean() {
- [ -z "$tmp" ] || rm -f "$tmp"
- tmp=""
- [ -z "$ref" ] || rm -f "$ref"
- ref=""
-}
sanitize_one() {
+ local file compress decompress tmp ref
file=$1
compress=""
echo $file | grep -qs 'gz$' && compress=gzip
@@ -550,11 +554,10 @@ sanitize_one() {
compress=cat
decompress=cat
fi
- trap sanitize_one_clean 0
tmp=`mktemp`
ref=`mktemp`
+ add_tmpfiles $tmp $ref
if [ -z "$tmp" -o -z "$ref" ]; then
- sanitize_one_clean
fatal "cannot create temporary files"
fi
touch -r $file $ref # save the mtime
@@ -564,12 +567,7 @@ sanitize_one() {
$decompress | sanitize_xml_attrs | $compress
fi < $file > $tmp
mv $tmp $file
- # note: cleaning $tmp up is still needed even after it's renamed
- # because its temp directory is still there.
-
touch -r $ref $file
- sanitize_one_clean
- trap "" 0
}
#
@@ -599,10 +597,28 @@ pickfirst() {
return 1
}
+# tmp files business
+drop_tmpfiles() {
+ trap 'rm -rf `cat $__TMPFLIST`; rm $__TMPFLIST' EXIT
+}
+init_tmpfiles() {
+ if __TMPFLIST=`mktemp`; then
+ drop_tmpfiles
+ else
+ # this is really bad, let's just leave
+ fatal "eek, mktemp cannot create temporary files"
+ fi
+}
+add_tmpfiles() {
+ test -f "$__TMPFLIST" || return
+ echo $* >> $__TMPFLIST
+}
+
#
# get some system info
#
distro() {
+ local relf f
which lsb_release >/dev/null 2>&1 && {
lsb_release -d
debug "using lsb_release for distribution info"
@@ -622,42 +638,42 @@ distro() {
warning "no lsb_release, no /etc/*-release, no /etc/debian_version: no distro information"
}
+pkg_ver_deb() {
+ dpkg-query -f '${Name} ${Version}' -W $* 2>/dev/null
+ debsums -s $* 2>/dev/null
+}
+pkg_ver_rpm() {
+ {
+ rpm -q --qf '%{name} %{version}-%{release} - %{distribution} %{arch}\n' $*
+ rpm --verify $*
+ } 2>&1 | grep -v 'not installed'
+}
+pkg_ver_pkg_info() {
+ for pkg; do
+ pkg_info | grep $pkg
+ done
+}
+pkg_ver_pkginfo() {
+ for pkg; do
+ pkginfo $pkg | awk '{print $3}' # format?
+ done
+}
pkg_ver() {
+ local pkg_mgr
if which dpkg >/dev/null 2>&1 ; then
- pkg_mgr="deb"
+ pkg_mgr="deb"
elif which rpm >/dev/null 2>&1 ; then
- pkg_mgr="rpm"
+ pkg_mgr="rpm"
elif which pkg_info >/dev/null 2>&1 ; then
- pkg_mgr="pkg_info"
+ pkg_mgr="pkg_info"
elif which pkginfo >/dev/null 2>&1 ; then
- pkg_mgr="pkginfo"
+ pkg_mgr="pkginfo"
else
- echo "Unknown package manager!"
- return
+ echo "Unknown package manager!"
+ return
fi
debug "the package manager is $pkg_mgr"
-
- # for Linux .deb based systems
- for pkg ; do
- case $pkg_mgr in
- deb)
- if dpkg-query -f '${Name} ${Version}' -W $pkg 2>/dev/null ; then
- debsums -s $pkg 2>/dev/null
- fi
- ;;
- rpm)
- if rpm -q --qf '%{name} %{version}-%{release} - %{distribution} %{arch}\n' $pkg ; then
- rpm --verify $pkg
- fi
- ;;
- pkg_info)
- pkg_info | grep $pkg
- ;;
- pkginfo)
- pkginfo | awk '{print $3}' # format?
- ;;
- esac
- done
+ pkg_ver_$pkg_mgr $*
}
crm_info() {
diff --git a/include/clplumbing/cl_uuid.h b/include/clplumbing/cl_uuid.h
index 7f53f5c..12542cd 100644
--- a/include/clplumbing/cl_uuid.h
+++ b/include/clplumbing/cl_uuid.h
@@ -16,7 +16,7 @@
#ifndef _CL_UUID_H_
#define _CL_UUID_H_
-#include <glib/gtypes.h>
+#include <glib.h>
typedef struct cl_uuid_s{
unsigned char uuid[16];
diff --git a/include/clplumbing/ipc.h b/include/clplumbing/ipc.h
index fcf7694..4a5e151 100644
--- a/include/clplumbing/ipc.h
+++ b/include/clplumbing/ipc.h
@@ -701,7 +701,7 @@ extern IPC_Auth * ipc_set_auth(uid_t * a_uid, gid_t * a_gid
extern void ipc_destroy_auth(IPC_Auth * auth);
extern void ipc_set_pollfunc(int (*)(struct pollfd*, unsigned int, int));
-
+extern void ipc_bufpool_dump_stats(void);
#ifdef IPC_TIME_DEBUG
diff --git a/include/compress.h b/include/compress.h
index e1e4977..9cd733c 100644
--- a/include/compress.h
+++ b/include/compress.h
@@ -21,8 +21,8 @@
#ifndef _COMPRESS_H_
#define _COMPRESS_H_
-#define HB_COMPRESS_TYPE HBcompress
-#define HB_COMPRESS_TYPE_S "HBcompress"
+#define HB_COMPRESS_TYPE compress
+#define HB_COMPRESS_TYPE_S "compress"
/*
* List of functions provided by implementations of the heartbeat
diff --git a/lib/clplumbing/GSource.c b/lib/clplumbing/GSource.c
index 7f82360..48bb198 100644
--- a/lib/clplumbing/GSource.c
+++ b/lib/clplumbing/GSource.c
@@ -1506,6 +1506,7 @@ Gmain_timeout_add_full(gint priority
g_source_set_callback(source, function, data, notify);
append->gsourceid = g_source_attach(source, NULL);
+ g_source_unref(source);
return append->gsourceid;
}
@@ -1516,14 +1517,12 @@ Gmain_timeout_remove(guint tag)
GSource* source = g_main_context_find_source_by_id(NULL,tag);
struct GTimeoutAppend* append = GTIMEOUT(source);
- g_source_remove(tag);
-
if (source == NULL){
cl_log(LOG_ERR, "Attempt to remove timeout (%u)"
" with NULL source", tag);
}else{
g_assert(IS_TIMEOUTSRC(append));
- g_source_unref(source);
+ g_source_remove(tag);
}
return;
diff --git a/lib/clplumbing/Gmain_timeout.c b/lib/clplumbing/Gmain_timeout.c
deleted file mode 100644
index 611c118..0000000
--- a/lib/clplumbing/Gmain_timeout.c
+++ /dev/null
@@ -1,198 +0,0 @@
-/*
- * Glib mainloop timeout handling code.
- *
- * These functions work correctly even if someone resets the
- * time-of-day clock. The g_main_timeout_add() function does not have
- * this property, since it relies on gettimeofday().
- *
- * Our functions have the same semantics - except they always work ;-)
- *
- * This is because we use longclock_t for our time values.
- *
- * Copyright (c) 2002 Alan Robertson <alanr at unix.sh>
- *
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
-#if 0
-#include <glib.h>
-#include <clplumbing/longclock.h>
-#include <clplumbing/cl_log.h>
-#include <clplumbing/Gmain_timeout.h>
-#include <string.h>
-
-
-static gboolean
-Gmain_timeout_prepare(GSource* src, gint* timeout);
-
-static gboolean
-Gmain_timeout_check(GSource* src);
-
-static gboolean
-Gmain_timeout_dispatch(GSource* src, GSourceFunc func, gpointer user_data);
-
-static GSourceFuncs Gmain_timeout_funcs = {
- prepare: Gmain_timeout_prepare,
- check: Gmain_timeout_check,
- dispatch: Gmain_timeout_dispatch,
-};
-
-
-struct GTimeoutAppend {
- GSource Source;
- longclock_t nexttime;
- guint interval;
- unsigned long maxdispatchdelayms;
- unsigned long maxdispatchms;
-};
-
-#define GTIMEOUT(GS) ((struct GTimeoutAppend*)((void*)(GS)))
-
-guint
-Gmain_timeout_add(guint interval
-, GSourceFunc function
-, gpointer data)
-{
- return Gmain_timeout_add_full(G_PRIORITY_DEFAULT
- , interval, function, data, NULL);
-}
-
-guint
-Gmain_timeout_add_full(gint priority
-, guint interval
-, GSourceFunc function
-, gpointer data
-, GDestroyNotify notify)
-{
-
- struct GTimeoutAppend* append;
-
- GSource* source = g_source_new( &Gmain_timeout_funcs,
- sizeof(struct GTimeoutAppend));
-
- append = GTIMEOUT(source);
-
- append->nexttime = add_longclock(time_longclock()
- ,msto_longclock(interval));
- append->interval = interval;
- append->maxdispatchms = 0;
- append->maxdispatchdelayms = 10000;
-
- g_source_set_priority(source, priority);
-
- g_source_set_can_recurse(source, FALSE);
-
- g_source_set_callback(source, function, data, notify);
-
- return g_source_attach(source, NULL);
-
-}
-
-void
-Gmain_timeout_remove(guint tag)
-{
- GSource* source = g_main_context_find_source_by_id(NULL,tag);
-
- g_source_remove(tag);
-
- if (source != NULL){
- g_source_unref(source);
- }
-
- return;
-}
-
-/* g_main_loop-style prepare function */
-static gboolean
-Gmain_timeout_prepare(GSource* src, gint* timeout)
-{
-
- struct GTimeoutAppend* append = GTIMEOUT(src);
- longclock_t lnow = time_longclock();
- longclock_t remain;
-
- if (cmp_longclock(lnow, append->nexttime) >= 0) {
- *timeout = 0L;
- return TRUE;
- }
- /* This is safe - we will always have a positive result */
- remain = sub_longclock(append->nexttime, lnow);
- /* This is also safe - we started out in 'ms' */
- *timeout = longclockto_ms(remain);
- return ((*timeout) == 0);
-}
-
-/* g_main_loop-style check function */
-static gboolean
-Gmain_timeout_check (GSource* src)
-{
- struct GTimeoutAppend* append = GTIMEOUT(src);
- longclock_t lnow = time_longclock();
-
- if (cmp_longclock(lnow, append->nexttime) >= 0) {
- return TRUE;
- }
- return FALSE;
-}
-
-/* g_main_loop-style dispatch function */
-static gboolean
-Gmain_timeout_dispatch(GSource* src, GSourceFunc func, gpointer user_data)
-{
- struct GTimeoutAppend* append = GTIMEOUT(src);
- longclock_t lstart = time_longclock();
- long ms = longclockto_ms(sub_longclock(lstart, append->nexttime));
- gboolean ret;
-
- if (append->maxdispatchdelayms > 0 && ms > append->maxdispatchdelayms) {
- cl_log(LOG_WARNING, "Timeout dispatch function [%lx] called %ld ms late."
- , (unsigned long)func, ms);
- }
-
-
- /* Schedule our next dispatch */
- append->nexttime = add_longclock(time_longclock()
- , msto_longclock(append->interval));
-
- /* Then call the user function */
- ret = func(user_data);
-
- /* Time it if requested */
- if (append->maxdispatchms > 0) {
- longclock_t lend = time_longclock();
- ms = longclockto_ms(sub_longclock(lend, lstart));
- if (ms > append->maxdispatchms) {
- cl_log(LOG_WARNING, "Timeout dispatch function [%lx] took %ld ms."
- , (unsigned long)func, ms);
- }
- }
- return ret;
-}
-
-void
-Gmain_timeout_setmaxdispatchtime(GSource* src, long dispatchms)
-{
- struct GTimeoutAppend* append = GTIMEOUT(src);
- append->maxdispatchms = dispatchms;
-}
-
-void
-Gmain_timeout_setmaxdispatchdelay(GSource* src, long delayms)
-{
- struct GTimeoutAppend* append = GTIMEOUT(src);
- append->maxdispatchdelayms = delayms;
-}
-#endif
diff --git a/lib/clplumbing/Makefile.am b/lib/clplumbing/Makefile.am
index b2d71cb..1b504fc 100644
--- a/lib/clplumbing/Makefile.am
+++ b/lib/clplumbing/Makefile.am
@@ -48,7 +48,6 @@ libplumb_la_SOURCES = \
cl_reboot.c \
coredumps.c \
cpulimits.c \
- Gmain_timeout.c \
GSource.c \
ipcsocket.c \
longclock.c \
diff --git a/lib/clplumbing/cl_compress.c b/lib/clplumbing/cl_compress.c
index bcb6d19..6b56ad6 100644
--- a/lib/clplumbing/cl_compress.c
+++ b/lib/clplumbing/cl_compress.c
@@ -47,7 +47,7 @@
* it is using the new compression. For back compatibility, the default is legacy mode.
*
* The real compression work is done by compression plugins. There are two plugins right
- * now: zlib and bz2, they are in lib/plugins/HBcompress
+ * now: zlib and bz2, they are in lib/plugins/compress
*
*/
@@ -72,13 +72,15 @@
#define COMPRESSED_FIELD "_compressed_payload"
#define COMPRESS_NAME "_compression_algorithm"
#define HACOMPRESSNAME "HA_COMPRESSION"
+#define DFLT_COMPRESS_PLUGIN "bz2"
+
static struct hb_compress_fns* msg_compress_fns = NULL;
static char* compress_name = NULL;
GHashTable* CompressFuncs = NULL;
static PILGenericIfMgmtRqst Reqs[] =
{
- {"HBcompress", &CompressFuncs, NULL, NULL, NULL},
+ {"compress", &CompressFuncs, NULL, NULL, NULL},
{NULL, NULL, NULL, NULL, NULL}
};
@@ -168,6 +170,15 @@ cl_set_compress_fns(const char* pluginname)
struct hb_compress_fns*
cl_get_compress_fns(void)
{
+ static int try_dflt = 1;
+
+ if (try_dflt && !msg_compress_fns) {
+ try_dflt = 0;
+ cl_log(LOG_INFO, "%s: user didn't set compression type, "
+ "loading %s plugin",
+ __FUNCTION__, DFLT_COMPRESS_PLUGIN);
+ cl_compress_load_plugin(DFLT_COMPRESS_PLUGIN);
+ }
return msg_compress_fns;
}
@@ -185,8 +196,6 @@ get_compress_fns(const char* pluginname)
funcs = g_hash_table_lookup(CompressFuncs, pluginname);
return funcs;
-
-
}
void cl_realtime_malloc_check(void);
diff --git a/lib/clplumbing/cl_msg.c b/lib/clplumbing/cl_msg.c
index afb6830..22f00e3 100644
--- a/lib/clplumbing/cl_msg.c
+++ b/lib/clplumbing/cl_msg.c
@@ -52,10 +52,10 @@
#define UUID_SLEN 64
#define MAXCHILDMSGLEN 512
-static int compression_threshold = (2*1024);
+static int compression_threshold = (128*1024);
static enum cl_msgfmt msgfmt = MSGFMT_NVPAIR;
-static gboolean use_traditional_compression = TRUE;
+static gboolean use_traditional_compression = FALSE;
const char*
FT_strings[]={
@@ -2308,8 +2308,6 @@ msg2string_buf(const struct ha_msg *m, char* buf, size_t len
strcat(bp,"\n");
bp++;
-
-
}
if (needhead){
CHECKROOM_CONST(MSG_END);
@@ -2338,15 +2336,8 @@ msg2string(const struct ha_msg *m)
len = get_stringlen(m);
- if (len >= MAXMSG){
- cl_log(LOG_ERR, "msg2string: msg is too large"
- "len =%d,MAX msg allowed=%d", len, MAXMSG);
- return NULL;
- }
-
buf = malloc(len);
-
if (buf == NULL) {
cl_log(LOG_ERR, "msg2string: no memory for string");
return(NULL);
@@ -2378,6 +2369,7 @@ must_use_netstring(const struct ha_msg* msg)
}
+#define use_netstring(m) (msgfmt == MSGFMT_NETSTRING || must_use_netstring(m))
static char*
msg2wirefmt_ll(struct ha_msg*m, size_t* len, int flag)
@@ -2385,23 +2377,16 @@ msg2wirefmt_ll(struct ha_msg*m, size_t* len, int flag)
int wirefmtlen;
int i;
- char* ret;
-
+ int netstg = use_netstring(m);
- if (msgfmt == MSGFMT_NETSTRING){
- wirefmtlen = get_netstringlen(m);
- }else{
- wirefmtlen = get_stringlen(m);
- }
-
+ wirefmtlen = netstg ? get_netstringlen(m) : get_stringlen(m);
if (use_traditional_compression
&&(flag & MSG_NEEDCOMPRESS)
&& (wirefmtlen> compression_threshold)
&& cl_get_compress_fns() != NULL){
return cl_compressmsg(m, len);
}
-
-
+
if (flag & MSG_NEEDCOMPRESS){
for (i=0 ;i < m->nfields; i++){
int type = m->types[i];
@@ -2410,69 +2395,45 @@ msg2wirefmt_ll(struct ha_msg*m, size_t* len, int flag)
}
}
}
-
-
- if (msgfmt == MSGFMT_NETSTRING || must_use_netstring(m)){
- wirefmtlen = get_netstringlen(m);
- if (!(flag&MSG_NOSIZECHECK) && wirefmtlen >= MAXMSG){
- cl_log(LOG_ERR, "%s: msg too big(%d)"
- "for netstring fmt",
- __FUNCTION__, wirefmtlen);
- return NULL;
- }
- if (flag& MSG_NEEDAUTH){
- return msg2netstring(m, len);
- }else{
- ret = msg2netstring_noauth(m, len);
- return ret;
+ wirefmtlen = netstg ? get_netstringlen(m) : get_stringlen(m);
+ if (wirefmtlen >= MAXMSG){
+ if (flag&MSG_NEEDCOMPRESS) {
+ if (cl_get_compress_fns() != NULL)
+ return cl_compressmsg(m, len);
}
-
-
- }else{
- char *tmp;
-
- wirefmtlen = get_stringlen(m);
- if (wirefmtlen >= MAXMSG){
- cl_log(LOG_ERR, "%s: msg too big(%d)"
- " for string fmt",
- __FUNCTION__, wirefmtlen);
- return NULL;
- }
-
- tmp = msg2string(m);
-
- if(tmp == NULL){
- *len = 0;
- return NULL;
- }
-
- *len = strlen(tmp) + 1;
- return(tmp);
+ cl_log(LOG_ERR, "%s: msg too big(%d)",
+ __FUNCTION__, wirefmtlen);
+ return NULL;
}
-
-
+ if (flag & MSG_NEEDAUTH) {
+ return msg2netstring(m, len);
+ }
+ return msg2wirefmt_noac(m, len);
}
-
char*
msg2wirefmt(struct ha_msg*m, size_t* len){
return msg2wirefmt_ll(m, len, MSG_NEEDAUTH|MSG_NEEDCOMPRESS);
}
-
char*
-msg2wirefmt_noac(struct ha_msg*m, size_t* len){
-
- /* in this execution path the size check is not necessary;
- * still, the msg2wirefmt_ll is invoked more than once for
- * the same message (or parts of it) which is somewhat
- * strange, though perhaps it helps reduce the code
- * complexity
- */
- return msg2wirefmt_ll(m, len, MSG_NOSIZECHECK);
-}
+msg2wirefmt_noac(struct ha_msg*m, size_t* len)
+{
+ if (use_netstring(m)) {
+ return msg2netstring_noauth(m, len);
+ } else {
+ char *tmp;
+ tmp = msg2string(m);
+ if(tmp == NULL){
+ *len = 0;
+ return NULL;
+ }
+ *len = strlen(tmp) + 1;
+ return tmp;
+ }
+}
static struct ha_msg*
wirefmt2msg_ll(const char* s, size_t length, int need_auth)
diff --git a/lib/clplumbing/cl_plugin.c b/lib/clplumbing/cl_plugin.c
index 419b655..c039a35 100644
--- a/lib/clplumbing/cl_plugin.c
+++ b/lib/clplumbing/cl_plugin.c
@@ -45,7 +45,7 @@ static PILPluginUniv* plugin_univ = NULL;
static PILGenericIfMgmtRqst reqs[] =
{
- {"HBcompress", &funcstable[0], NULL, NULL, NULL},
+ {"compress", &funcstable[0], NULL, NULL, NULL},
{"HBcoms", &funcstable[1], NULL, NULL, NULL},
{"HBauth", &funcstable[2], NULL, NULL, NULL},
{"RAExec", &funcstable[3], NULL, NULL, NULL},
diff --git a/lib/clplumbing/ipcsocket.c b/lib/clplumbing/ipcsocket.c
index 4341daf..804cd11 100644
--- a/lib/clplumbing/ipcsocket.c
+++ b/lib/clplumbing/ipcsocket.c
@@ -11,12 +11,12 @@
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
@@ -87,21 +87,14 @@
# endif
#endif
-
#if HB_IPC_METHOD == HB_IPC_SOCKET
-
# include <sys/poll.h>
# include <netinet/in.h>
# include <sys/un.h>
-
#elif HB_IPC_METHOD == HB_IPC_STREAM
-
# include <stropts.h>
-
#else
-
# error "IPC type invalid"
-
#endif
#include <sys/ioctl.h>
@@ -191,12 +184,11 @@ struct SOCKET_CH_PRIVATE{
uid_t farside_uid;
gid_t farside_gid;
#endif
-
+
/* the buf used to save unfinished message */
struct IPC_MESSAGE *buf_msg;
};
-
struct IPC_Stats {
long nsent;
long noutqueued;
@@ -215,11 +207,8 @@ extern int debug_level;
/* unix domain socket implementations of IPC functions. */
-
-
static int socket_resume_io(struct IPC_CHANNEL *ch);
-
static struct IPC_MESSAGE* socket_message_new(struct IPC_CHANNEL*ch
, int msg_len);
@@ -248,12 +237,10 @@ static int socket_resume_io_read(struct IPC_CHANNEL *ch, int*, gboolean read1any
static struct IPC_OPS socket_ops;
static gboolean ipc_time_debug_flag = TRUE;
-
void
set_ipc_time_debug_flag(gboolean flag)
{
ipc_time_debug_flag = flag;
-
}
#ifdef IPC_TIME_DEBUG
@@ -282,17 +269,16 @@ get_enqueue_time(IPC_Message *ipcmsg)
return t;
}
-int
+int
timediff(longclock_t t1, longclock_t t2)
{
longclock_t remain;
-
+
remain = sub_longclock(t1, t2);
-
+
return longclockto_ms(remain);
}
-
void
ipc_time_debug(IPC_Channel* ch, IPC_Message* ipcmsg, int whichpos)
{
@@ -304,23 +290,23 @@ ipc_time_debug(IPC_Channel* ch, IPC_Message* ipcmsg, int whichpos)
"recv",
"dequeue"};
- if (ipc_time_debug_flag == FALSE){
+ if (ipc_time_debug_flag == FALSE) {
return ;
}
if (ipcmsg->msg_body == NULL
- || ipcmsg->msg_buf == NULL){
+ || ipcmsg->msg_buf == NULL) {
cl_log(LOG_ERR, "msg_body =%p, msg_bu=%p",
ipcmsg->msg_body, ipcmsg->msg_buf);
abort();
return;
}
- switch(whichpos){
- case MSGPOS_ENQUEUE:
- SET_ENQUEUE_TIME(ipcmsg, lnow);
+ switch(whichpos) {
+ case MSGPOS_ENQUEUE:
+ SET_ENQUEUE_TIME(ipcmsg, lnow);
break;
- case MSGPOS_SEND:
+ case MSGPOS_SEND:
SET_SEND_TIME(ipcmsg, lnow);
goto checktime;
case MSGPOS_RECV:
@@ -328,23 +314,23 @@ ipc_time_debug(IPC_Channel* ch, IPC_Message* ipcmsg, int whichpos)
goto checktime;
case MSGPOS_DEQUEUE:
SET_DEQUEUE_TIME(ipcmsg, lnow);
-
- checktime:
+
+ checktime:
msdiff = timediff(lnow, get_enqueue_time(ipcmsg));
- if (msdiff > MAXIPCTIME){
+ if (msdiff > MAXIPCTIME) {
struct ha_msg* hamsg = NULL;
- cl_log(LOG_WARNING,
+ cl_log(LOG_WARNING,
" message delayed from enqueue to %s %d ms "
"(enqueue-time=%lu, peer pid=%d) ",
positions[whichpos],
msdiff,
longclockto_ms(get_enqueue_time(ipcmsg)),
- ch->farside_pid);
+ ch->farside_pid);
(void)hamsg;
#if 0
hamsg = wirefmt2msg(ipcmsg->msg_body, ipcmsg->msg_len, 0);
- if (hamsg != NULL){
+ if (hamsg != NULL) {
struct ha_msg *crm_data = NULL;
crm_data = cl_get_struct(
hamsg, F_CRM_DATA);
@@ -357,7 +343,7 @@ ipc_time_debug(IPC_Channel* ch, IPC_Message* ipcmsg, int whichpos)
cl_msg_remove_value(
hamsg, crm_data);
}
-
+
cl_log_message(LOG_DEBUG, hamsg);
ha_msg_del(hamsg);
} else {
@@ -375,22 +361,15 @@ ipc_time_debug(IPC_Channel* ch, IPC_Message* ipcmsg, int whichpos)
}
}
#endif
-
+
}
break;
default:
cl_log(LOG_ERR, "wrong position value in IPC:%d", whichpos);
return;
}
-
- return;
}
-
-
-
-
-#endif
-
+#endif
void dump_ipc_info(const IPC_Channel* chan);
@@ -402,8 +381,6 @@ void dump_ipc_info(const IPC_Channel* chan);
# define CHANAUDIT(ch) socket_chan_audit(ch)
# define MAXPID 65535
-
-
static void
socket_chan_audit(const struct IPC_CHANNEL* ch)
{
@@ -411,7 +388,7 @@ socket_chan_audit(const struct IPC_CHANNEL* ch)
struct SOCKET_CH_PRIVATE *chp;
struct stat b;
-
+
if ((chp = ch->ch_private) == NULL) {
cl_log(LOG_CRIT, "Bad ch_private");
badch = TRUE;
@@ -433,7 +410,7 @@ socket_chan_audit(const struct IPC_CHANNEL* ch)
}
if (fstat(chp->s, &b) < 0) {
badch = TRUE;
- }else if ((b.st_mode & S_IFMT) != S_IFSOCK) {
+ } else if ((b.st_mode & S_IFMT) != S_IFSOCK) {
cl_log(LOG_CRIT, "channel @ 0x%lx: not a socket"
, (unsigned long)ch);
badch = TRUE;
@@ -478,10 +455,8 @@ socket_chan_audit(const struct IPC_CHANNEL* ch)
abort();
}
}
-
#endif
-
#ifdef CHEAT_CHECKS
long SeqNums[32];
@@ -508,7 +483,6 @@ static char SavedSentBody[32];
# define MIN(a,b) (a < b ? a : b)
#endif
-
static void
save_body(struct IPC_MESSAGE *msg, char * savearea, size_t length)
{
@@ -529,8 +503,7 @@ audit_readmsgq_msg(gpointer msg, gpointer user_data)
}
}
-
-static void
+static void
saveandcheck(struct IPC_CHANNEL * ch, struct IPC_MESSAGE* msg, char * savearea
, size_t savesize, long* lastseq, const char * text)
{
@@ -562,7 +535,7 @@ saveandcheck(struct IPC_CHANNEL * ch, struct IPC_MESSAGE* msg, char * savearea
, "SocketIPCStats.ninqueued = %ld"
, SocketIPCStats.ninqueued);
}
-
+
}
g_list_foreach(ch->recv_queue->queue, audit_readmsgq_msg, NULL);
if (cheatseq > 0) {
@@ -570,8 +543,6 @@ saveandcheck(struct IPC_CHANNEL * ch, struct IPC_MESSAGE* msg, char * savearea
}
}
-
-
# define CHECKFOO(which, ch, msg, area, text) { \
saveandcheck(ch,msg,area,sizeof(area),SeqNums+which,text); \
}
@@ -599,7 +570,6 @@ dump_msgq_msg(gpointer data, gpointer user_data)
dump_msg(data, user_data);
}
-
void
dump_ipc_info(const IPC_Channel* chan)
{
@@ -616,8 +586,8 @@ dump_ipc_info(const IPC_Channel* chan)
CHANAUDIT(chan);
}
-/* destroy socket wait channel */
-static void
+/* destroy socket wait channel */
+static void
socket_destroy_wait_conn(struct IPC_WAIT_CONNECTION * wait_conn)
{
struct SOCKET_WAIT_CONN_PRIVATE * wc = wait_conn->ch_private;
@@ -661,7 +631,7 @@ socket_destroy_wait_conn(struct IPC_WAIT_CONNECTION * wait_conn)
}
/* return a fd which can be listened on for new connections. */
-static int
+static int
socket_wait_selectfd(struct IPC_WAIT_CONNECTION *wait_conn)
{
struct SOCKET_WAIT_CONN_PRIVATE * wc = wait_conn->ch_private;
@@ -671,11 +641,10 @@ socket_wait_selectfd(struct IPC_WAIT_CONNECTION *wait_conn)
#elif HB_IPC_METHOD == HB_IPC_STREAM
return (wc == NULL ? -1 : wc->pipefds[0]);
#endif
-
}
/* socket accept connection. */
-static struct IPC_CHANNEL*
+static struct IPC_CHANNEL*
socket_accept_connection(struct IPC_WAIT_CONNECTION * wait_conn
, struct IPC_AUTH *auth_info)
{
@@ -696,10 +665,10 @@ socket_accept_connection(struct IPC_WAIT_CONNECTION * wait_conn
#elif HB_IPC_METHOD == HB_IPC_STREAM
struct strrecvfd strrecvfd;
#endif
-
+
/* get select fd */
- s = wait_conn->ops->get_select_fd(wait_conn);
+ s = wait_conn->ops->get_select_fd(wait_conn);
if (s < 0) {
cl_log(LOG_ERR, "get_select_fd: invalid fd");
return NULL;
@@ -720,20 +689,20 @@ socket_accept_connection(struct IPC_WAIT_CONNECTION * wait_conn
}
#endif
saveerrno=errno;
- if (new_sock == -1){
+ if (new_sock == -1) {
if (errno != EAGAIN && errno != EWOULDBLOCK) {
cl_perror("socket_accept_connection: accept(sock=%d)"
, s);
}
was_error = TRUE;
-
- }else{
+
+ } else {
if ((ch = socket_server_channel_new(new_sock)) == NULL) {
cl_log(LOG_ERR
, "socket_accept_connection:"
" Can't create new channel");
was_error = TRUE;
- }else{
+ } else {
conn_private=(struct SOCKET_WAIT_CONN_PRIVATE*)
( wait_conn->ch_private);
ch_private = (struct SOCKET_CH_PRIVATE *)(ch->ch_private);
@@ -759,26 +728,23 @@ socket_accept_connection(struct IPC_WAIT_CONNECTION * wait_conn
}
saveerrno=errno;
}
-
+
#if HB_IPC_METHOD == HB_IPC_SOCKET
g_free(peer_addr);
peer_addr = NULL;
#endif
errno=saveerrno;
return NULL;
-
}
-
-
-/*
- * Called by socket_destroy(). Disconnect the connection
- * and set ch_status to IPC_DISCONNECT.
+/*
+ * Called by socket_destroy(). Disconnect the connection
+ * and set ch_status to IPC_DISCONNECT.
*
* parameters :
* ch (IN) the pointer to the channel.
*
- * return values :
+ * return values :
* IPC_OK the connection is disconnected successfully.
* IPC_FAIL operation fails.
*/
@@ -801,9 +767,9 @@ socket_disconnect(struct IPC_CHANNEL* ch)
}
#endif
if (ch->ch_status == IPC_CONNECT) {
- socket_resume_io(ch);
+ socket_resume_io(ch);
}
-
+
if (conn_info->s >= 0) {
if (debug_level > 1) {
cl_log(LOG_DEBUG
@@ -822,16 +788,14 @@ socket_disconnect(struct IPC_CHANNEL* ch)
return IPC_OK;
}
-
-
-/*
+/*
* destroy a ipc queue and clean all memory space assigned to this queue.
* parameters:
* q (IN) the pointer to the queue which should be destroied.
*
* FIXME: This function does not free up messages that might
* be in the queue.
- */
+ */
static void
socket_destroy_queue(struct IPC_QUEUE * q)
@@ -841,8 +805,6 @@ socket_destroy_queue(struct IPC_QUEUE * q)
g_free((void *) q);
}
-
-
static void
socket_destroy_channel(struct IPC_CHANNEL * ch)
{
@@ -850,8 +812,8 @@ socket_destroy_channel(struct IPC_CHANNEL * ch)
if (ch->refcount > 0) {
return;
}
- if (ch->ch_status == IPC_CONNECT){
- socket_resume_io(ch);
+ if (ch->ch_status == IPC_CONNECT) {
+ socket_resume_io(ch);
}
if (debug_level > 1) {
cl_log(LOG_DEBUG, "socket_destroy(ch=0x%lx){"
@@ -861,7 +823,7 @@ socket_destroy_channel(struct IPC_CHANNEL * ch)
socket_destroy_queue(ch->send_queue);
socket_destroy_queue(ch->recv_queue);
- if (ch->pool){
+ if (ch->pool) {
ipc_bufpool_unref(ch->pool);
}
@@ -876,7 +838,7 @@ socket_destroy_channel(struct IPC_CHANNEL * ch)
g_free((void*)(priv->peer_addr));
}
#endif
- g_free((void*)(ch->ch_private));
+ g_free((void*)(ch->ch_private));
}
memset(ch, 0xff, sizeof(*ch));
g_free((void*)ch);
@@ -911,12 +873,10 @@ socket_check_disc_pending(struct IPC_CHANNEL* ch)
return IPC_BROKEN;
}
-
-
if (sockpoll.revents & POLLHUP) {
if (sockpoll.revents & POLLIN) {
ch->ch_status = IPC_DISC_PENDING;
- }else{
+ } else {
#if 1
cl_log(LOG_INFO, "HUP without input");
#endif
@@ -929,25 +889,23 @@ socket_check_disc_pending(struct IPC_CHANNEL* ch)
socket_resume_io_read(ch, &dummy, FALSE);
}
return IPC_OK;
-
}
-
-static int
+static int
socket_initiate_connection(struct IPC_CHANNEL * ch)
{
- struct SOCKET_CH_PRIVATE* conn_info;
+ struct SOCKET_CH_PRIVATE* conn_info;
#if HB_IPC_METHOD == HB_IPC_SOCKET
struct sockaddr_un peer_addr; /* connector's address information */
#elif HB_IPC_METHOD == HB_IPC_STREAM
#endif
-
+
conn_info = (struct SOCKET_CH_PRIVATE*) ch->ch_private;
-
+
#if HB_IPC_METHOD == HB_IPC_SOCKET
/* Prepare the socket */
memset(&peer_addr, 0, sizeof(peer_addr));
- peer_addr.sun_family = AF_LOCAL; /* host byte order */
+ peer_addr.sun_family = AF_LOCAL; /* host byte order */
if (strlen(conn_info->path_name) >= sizeof(peer_addr.sun_path)) {
return IPC_FAIL;
@@ -971,26 +929,22 @@ socket_initiate_connection(struct IPC_CHANNEL * ch)
static void
socket_set_high_flow_callback(IPC_Channel* ch,
flow_callback_t callback,
- void* userdata){
-
+ void* userdata) {
ch->high_flow_callback = callback;
ch->high_flow_userdata = userdata;
-
}
static void
socket_set_low_flow_callback(IPC_Channel* ch,
flow_callback_t callback,
- void* userdata){
-
+ void* userdata) {
ch->low_flow_callback = callback;
ch->low_flow_userdata = userdata;
-
}
static void
-socket_check_flow_control(struct IPC_CHANNEL* ch,
- int orig_qlen,
+socket_check_flow_control(struct IPC_CHANNEL* ch,
+ int orig_qlen,
int curr_qlen)
{
if (!IPC_ISRCONN(ch)) {
@@ -998,39 +952,40 @@ socket_check_flow_control(struct IPC_CHANNEL* ch,
}
if (curr_qlen >= ch->high_flow_mark
- && ch->high_flow_callback){
+ && ch->high_flow_callback) {
ch->high_flow_callback(ch, ch->high_flow_userdata);
- }
-
+ }
+
if (curr_qlen <= ch->low_flow_mark
&& orig_qlen > ch->low_flow_mark
- && ch->low_flow_callback){
- ch->low_flow_callback(ch, ch->low_flow_userdata);
- }
-
- return;
+ && ch->low_flow_callback) {
+ ch->low_flow_callback(ch, ch->low_flow_userdata);
+ }
}
-
-
-static int
+static int
socket_send(struct IPC_CHANNEL * ch, struct IPC_MESSAGE* msg)
{
-
int orig_qlen;
int diff;
struct IPC_MESSAGE* newmsg;
-
- if (msg->msg_len < 0 || msg->msg_len > MAXMSG) {
+
+ if (msg->msg_len > MAXMSG) {
+ cl_log(LOG_ERR, "%s: sorry, cannot send messages "
+ "bigger than %d (requested %lu)",
+ __FUNCTION__, MAXMSG, (unsigned long)msg->msg_len);
+ return IPC_FAIL;
+ }
+ if (msg->msg_len < 0) {
cl_log(LOG_ERR, "socket_send: "
- "invalid message");
+ "invalid message");
return IPC_FAIL;
}
-
- if (ch->ch_status != IPC_CONNECT){
+
+ if (ch->ch_status != IPC_CONNECT) {
return IPC_FAIL;
}
-
+
ch->ops->resume_io(ch);
if (ch->send_queue->maxqlen_cnt &&
@@ -1052,9 +1007,9 @@ socket_send(struct IPC_CHANNEL * ch, struct IPC_MESSAGE* msg)
return IPC_OK;
}
}
-
- while (ch->send_queue->current_qlen >= ch->send_queue->max_qlen){
- if (ch->ch_status != IPC_CONNECT){
+
+ while (ch->send_queue->current_qlen >= ch->send_queue->max_qlen) {
+ if (ch->ch_status != IPC_CONNECT) {
cl_log(LOG_WARNING, "socket_send:"
" message queue exceeded and IPC not connected");
return IPC_FAIL;
@@ -1062,55 +1017,51 @@ socket_send(struct IPC_CHANNEL * ch, struct IPC_MESSAGE* msg)
cl_shortsleep();
ch->ops->resume_io(ch);
}
-
+
/* add the message into the send queue */
CHECKFOO(0,ch, msg, SavedQueuedBody, "queued message");
SocketIPCStats.noutqueued++;
diff = 0;
- if (msg->msg_buf ){
- diff = (char*)msg->msg_body - (char*)msg->msg_buf;
+ if (msg->msg_buf ) {
+ diff = (char*)msg->msg_body - (char*)msg->msg_buf;
}
- if ( diff < (int)sizeof(struct SOCKET_MSG_HEAD) ){
+ if ( diff < (int)sizeof(struct SOCKET_MSG_HEAD) ) {
/* either we don't have msg->msg_buf set
* or we don't have enough bytes for socket head
- * we delete this message and creates
+ * we delete this message and creates
* a new one and delete the old one
*/
-
+
newmsg= socket_message_new(ch, msg->msg_len);
- if (newmsg == NULL){
+ if (newmsg == NULL) {
cl_log(LOG_ERR, "socket_resume_io_write: "
"allocating memory for new ipc msg failed");
return IPC_FAIL;
}
-
+
memcpy(newmsg->msg_body, msg->msg_body, msg->msg_len);
-
- if(msg->msg_done){
+
+ if(msg->msg_done) {
msg->msg_done(msg);
};
msg = newmsg;
- }
-
-
+ }
#ifdef IPC_TIME_DEBUG
ipc_time_debug(ch,msg, MSGPOS_ENQUEUE);
#endif
ch->send_queue->queue = g_list_append(ch->send_queue->queue,
msg);
orig_qlen = ch->send_queue->current_qlen++;
-
+
socket_check_flow_control(ch, orig_qlen, orig_qlen +1 );
-
+
/* resume io */
ch->ops->resume_io(ch);
return IPC_OK;
-
-
}
-static int
+static int
socket_recv(struct IPC_CHANNEL * ch, struct IPC_MESSAGE** message)
{
GList *element;
@@ -1170,7 +1121,7 @@ socket_check_poll(struct IPC_CHANNEL * ch
ch->ch_status = IPC_DISCONNECT;
return IPC_BROKEN;
- }else if (sockpoll->revents & (POLLNVAL|POLLERR)) {
+ } else if (sockpoll->revents & (POLLNVAL|POLLERR)) {
/* Have we already closed the socket? */
if (fcntl(sockpoll->fd, F_GETFL) < 0) {
cl_perror("socket_check_poll(pid %d): bad fd [%d]"
@@ -1202,12 +1153,12 @@ socket_waitfor(struct IPC_CHANNEL * ch
return IPC_BROKEN;
}
sockpoll.fd = ch->ops->get_recv_select_fd(ch);
-
+
while (!finished(ch) && IPC_ISRCONN(ch)) {
int rc;
sockpoll.events = POLLIN;
-
+
/* Cannot call resume_io after the call to finished()
* and before the call to poll because we might
* change the state of the thing finished() is
@@ -1220,13 +1171,13 @@ socket_waitfor(struct IPC_CHANNEL * ch
if (ch->send_queue->current_qlen > 0) {
sockpoll.events |= POLLOUT;
}
-
+
rc = ipc_pollfunc_ptr(&sockpoll, 1, -1);
-
+
if (rc < 0) {
return (errno == EINTR ? IPC_INTR : IPC_FAIL);
}
-
+
rc = socket_check_poll(ch, &sockpoll);
if (sockpoll.revents & POLLIN) {
socket_resume_io(ch);
@@ -1262,19 +1213,18 @@ socket_waitout(struct IPC_CHANNEL * ch)
if (rc != IPC_OK) {
cl_log(LOG_ERR
, "socket_waitout failure: rc = %d", rc);
- }else if (ch->ops->is_sending_blocked(ch)) {
+ } else if (ch->ops->is_sending_blocked(ch)) {
cl_log(LOG_ERR, "socket_waitout output still blocked");
}
CHANAUDIT(ch);
return rc;
}
-
static gboolean
socket_is_message_pending(struct IPC_CHANNEL * ch)
{
-
int nbytes;
+
socket_resume_io_read(ch, &nbytes, TRUE);
ch->ops->resume_io(ch);
if (ch->recv_queue->current_qlen > 0) {
@@ -1287,9 +1237,7 @@ socket_is_message_pending(struct IPC_CHANNEL * ch)
static gboolean
socket_is_output_pending(struct IPC_CHANNEL * ch)
{
-
socket_resume_io(ch);
-
return ch->ch_status == IPC_CONNECT
&& ch->send_queue->current_qlen > 0;
}
@@ -1301,25 +1249,20 @@ socket_is_sendq_full(struct IPC_CHANNEL * ch)
return(ch->send_queue->current_qlen == ch->send_queue->max_qlen);
}
-
static gboolean
socket_is_recvq_full(struct IPC_CHANNEL * ch)
{
ch->ops->resume_io(ch);
- return(ch->recv_queue->current_qlen == ch->recv_queue->max_qlen);
+ return(ch->recv_queue->current_qlen == ch->recv_queue->max_qlen);
}
-
static int
socket_get_conntype(struct IPC_CHANNEL* ch)
{
return ch->conntype;
-
}
-
-
-static int
+static int
socket_assert_auth(struct IPC_CHANNEL *ch, GHashTable *auth)
{
cl_log(LOG_ERR
@@ -1327,9 +1270,6 @@ socket_assert_auth(struct IPC_CHANNEL *ch, GHashTable *auth)
return IPC_FAIL;
}
-
-
-
static int
socket_resume_io_read(struct IPC_CHANNEL *ch, int* nbytes, gboolean read1anyway)
{
@@ -1343,49 +1283,44 @@ socket_resume_io_read(struct IPC_CHANNEL *ch, int* nbytes, gboolean read1anyway)
int nmsgs = 0;
int spaceneeded;
*nbytes = 0;
-
+
CHANAUDIT(ch);
conn_info = (struct SOCKET_CH_PRIVATE *) ch->ch_private;
if (ch->ch_status == IPC_DISCONNECT) {
return IPC_BROKEN;
}
-
- if (pool == NULL){
+
+ if (pool == NULL) {
ch->pool = pool = ipc_bufpool_new(0);
- if (pool == NULL){
+ if (pool == NULL) {
cl_log(LOG_ERR, "socket_resume_io_read: "
"memory allocation for ipc pool failed");
- exit(1);
+ return IPC_FAIL;
}
}
-
- if (ipc_bufpool_full(pool, ch, &spaceneeded)){
-
+
+ if (ipc_bufpool_full(pool, ch, &spaceneeded)) {
struct ipc_bufpool* newpool;
-
+
newpool = ipc_bufpool_new(spaceneeded);
- if (newpool == NULL){
+ if (newpool == NULL) {
cl_log(LOG_ERR, "socket_resume_io_read: "
"memory allocation for a new ipc pool failed");
- exit(1);
+ return IPC_FAIL;
}
-
+
ipc_bufpool_partial_copy(newpool, pool);
ipc_bufpool_unref(pool);
ch->pool = pool = newpool;
}
-
-
if (maxqlen <= 0 && read1anyway) {
maxqlen = 1;
}
if (ch->recv_queue->current_qlen < maxqlen && retcode == IPC_OK) {
-
void * msg_begin;
int msg_len;
int len;
-
#if HB_IPC_METHOD == HB_IPC_STREAM
struct strbuf d;
int flags, rc;
@@ -1396,9 +1331,9 @@ socket_resume_io_read(struct IPC_CHANNEL *ch, int* nbytes, gboolean read1anyway)
len = ipc_bufpool_spaceleft(pool);
msg_begin = pool->currpos;
-
+
CHANAUDIT(ch);
-
+
/* Now try to receive some data */
#if HB_IPC_METHOD == HB_IPC_SOCKET
@@ -1414,23 +1349,23 @@ socket_resume_io_read(struct IPC_CHANNEL *ch, int* nbytes, gboolean read1anyway)
SocketIPCStats.last_recv_rc = msg_len;
SocketIPCStats.last_recv_errno = errno;
++SocketIPCStats.recv_count;
-
+
/* Did we get an error? */
if (msg_len < 0) {
switch (errno) {
case EAGAIN:
- if (ch->ch_status==IPC_DISC_PENDING){
+ if (ch->ch_status==IPC_DISC_PENDING) {
ch->ch_status =IPC_DISCONNECT;
retcode = IPC_BROKEN;
}
break;
-
+
case ECONNREFUSED:
- case ECONNRESET:
+ case ECONNRESET:
ch->ch_status = IPC_DISC_PENDING;
retcode= socket_check_disc_pending(ch);
break;
-
+
default:
cl_perror("socket_resume_io_read"
": unknown recv error, peerpid=%d",
@@ -1439,39 +1374,38 @@ socket_resume_io_read(struct IPC_CHANNEL *ch, int* nbytes, gboolean read1anyway)
retcode = IPC_FAIL;
break;
}
-
- }else if (msg_len == 0) {
+
+ } else if (msg_len == 0) {
ch->ch_status = IPC_DISC_PENDING;
if(ch->recv_queue->current_qlen <= 0) {
ch->ch_status = IPC_DISCONNECT;
retcode = IPC_FAIL;
}
- }else {
+ } else {
/* We read something! */
/* Note that all previous cases break out of the loop */
debug_bytecount += msg_len;
*nbytes = msg_len;
nmsgs = ipc_bufpool_update(pool, ch, msg_len, ch->recv_queue) ;
-
+
SocketIPCStats.ninqueued += nmsgs;
-
+
}
}
-
/* Check for errors uncaught by recv() */
/* NOTE: It doesn't seem right we have to do this every time */
/* FIXME?? */
-
- memset(&sockpoll,0, sizeof(struct pollfd));
- if ((retcode == IPC_OK)
+
+ memset(&sockpoll,0, sizeof(struct pollfd));
+ if ((retcode == IPC_OK)
&& (sockpoll.fd = conn_info->s) >= 0) {
/* Just check for errors, not for data */
sockpoll.events = 0;
ipc_pollfunc_ptr(&sockpoll, 1, 0);
retcode = socket_check_poll(ch, &sockpoll);
}
-
+
CHANAUDIT(ch);
if (retcode != IPC_OK) {
return retcode;
@@ -1480,19 +1414,16 @@ socket_resume_io_read(struct IPC_CHANNEL *ch, int* nbytes, gboolean read1anyway)
return IPC_ISRCONN(ch) ? IPC_OK : IPC_BROKEN;
}
-
static int
socket_resume_io_write(struct IPC_CHANNEL *ch, int* nmsg)
{
int retcode = IPC_OK;
struct SOCKET_CH_PRIVATE* conn_info;
-
-
+
CHANAUDIT(ch);
*nmsg = 0;
conn_info = (struct SOCKET_CH_PRIVATE *) ch->ch_private;
-
-
+
while (ch->ch_status == IPC_CONNECT
&& retcode == IPC_OK
&& ch->send_queue->current_qlen > 0) {
@@ -1506,7 +1437,7 @@ socket_resume_io_write(struct IPC_CHANNEL *ch, int* nmsg)
char* p;
unsigned int bytes_remaining;
int diff;
-
+
CHANAUDIT(ch);
element = g_list_first(ch->send_queue->queue);
if (element == NULL) {
@@ -1515,20 +1446,20 @@ socket_resume_io_write(struct IPC_CHANNEL *ch, int* nmsg)
break;
}
msg = (struct IPC_MESSAGE *) (element->data);
-
+
diff = 0;
- if (msg->msg_buf ){
- diff = (char*)msg->msg_body - (char*)msg->msg_buf;
+ if (msg->msg_buf ) {
+ diff = (char*)msg->msg_body - (char*)msg->msg_buf;
}
- if ( diff < (int)sizeof(struct SOCKET_MSG_HEAD) ){
+ if ( diff < (int)sizeof(struct SOCKET_MSG_HEAD) ) {
/* either we don't have msg->msg_buf set
* or we don't have enough bytes for socket head
- * we delete this message and creates
+ * we delete this message and creates
* a new one and delete the old one
*/
-
+
newmsg= socket_message_new(ch, msg->msg_len);
- if (newmsg == NULL){
+ if (newmsg == NULL) {
cl_log(LOG_ERR, "socket_resume_io_write: "
"allocating memory for new ipc msg failed");
return IPC_FAIL;
@@ -1538,29 +1469,27 @@ socket_resume_io_write(struct IPC_CHANNEL *ch, int* nmsg)
oldmsg = msg;
msg = newmsg;
}
-
+
head.msg_len = msg->msg_len;
head.magic = HEADMAGIC;
memcpy(msg->msg_buf, &head, sizeof(struct SOCKET_MSG_HEAD));
-
- if (ch->bytes_remaining == 0){
- /*we start to send a new message*/
-#ifdef IPC_TIME_DEBUG
- ipc_time_debug(ch, msg, MSGPOS_SEND);
-#endif
-
+ if (ch->bytes_remaining == 0) {
+ /*we start to send a new message*/
+#ifdef IPC_TIME_DEBUG
+ ipc_time_debug(ch, msg, MSGPOS_SEND);
+#endif
bytes_remaining = msg->msg_len + ch->msgpad;
p = msg->msg_buf;
- }else {
+ } else {
bytes_remaining = ch->bytes_remaining;
p = ((char*)msg->msg_buf) + msg->msg_len + ch->msgpad
- bytes_remaining;
-
+
}
-
+
sendrc = 0;
-
+
do {
#if HB_IPC_METHOD == HB_IPC_STREAM
struct strbuf d;
@@ -1577,24 +1506,23 @@ socket_resume_io_write(struct IPC_CHANNEL *ch, int* nmsg)
d.len = msglen = bytes_remaining;
d.buf = p;
putmsgrc = putmsg(conn_info->s, NULL, &d, 0);
- sendrc = putmsgrc == 0 ? msglen : -1;
+ sendrc = putmsgrc == 0 ? msglen : -1;
#endif
SocketIPCStats.last_send_rc = sendrc;
SocketIPCStats.last_send_errno = errno;
++SocketIPCStats.send_count;
-
- if (sendrc <= 0){
+
+ if (sendrc <= 0) {
break;
- }else {
+ } else {
p = p + sendrc;
bytes_remaining -= sendrc;
}
} while(bytes_remaining > 0 );
-
ch->bytes_remaining = bytes_remaining;
-
+
if (sendrc < 0) {
switch (errno) {
case EAGAIN:
@@ -1613,24 +1541,24 @@ socket_resume_io_write(struct IPC_CHANNEL *ch, int* nmsg)
break;
}
break;
- }else{
+ } else {
int orig_qlen;
CHECKFOO(3,ch, msg, SavedSentBody, "sent message")
- if (oldmsg){
+ if (oldmsg) {
if (msg->msg_done != NULL) {
msg->msg_done(msg);
}
msg=oldmsg;
}
-
- if(ch->bytes_remaining ==0){
- ch->send_queue->queue = g_list_remove(ch->send_queue->queue, msg);
+
+ if(ch->bytes_remaining ==0) {
+ ch->send_queue->queue = g_list_remove(ch->send_queue->queue, msg);
if (msg->msg_done != NULL) {
msg->msg_done(msg);
}
-
+
SocketIPCStats.nsent++;
orig_qlen = ch->send_queue->current_qlen--;
socket_check_flow_control(ch, orig_qlen, orig_qlen -1 );
@@ -1645,8 +1573,6 @@ socket_resume_io_write(struct IPC_CHANNEL *ch, int* nmsg)
return IPC_ISRCONN(ch) ? IPC_OK : IPC_BROKEN;
}
-
-
static int
socket_resume_io(struct IPC_CHANNEL *ch)
{
@@ -1660,27 +1586,19 @@ socket_resume_io(struct IPC_CHANNEL *ch)
if (!IPC_ISRCONN(ch)) {
return IPC_BROKEN;
}
-
-
-
+
do {
- if (nbytes_r > 0){
+ if (nbytes_r > 0) {
rc1 = socket_resume_io_read(ch, &nbytes_r, FALSE);
}
-
- if (nwmsg > 0){
+ if (nwmsg > 0) {
nwmsg = 0;
rc2 = socket_resume_io_write(ch, &nwmsg);
}
-
if (rc1 == IPC_OK || rc2 == IPC_OK) {
OKonce = TRUE;
}
-
} while ((nbytes_r > 0 || nwmsg > 0) && IPC_ISRCONN(ch));
-
-
-
if (IPC_ISRCONN(ch)) {
if (rc1 != IPC_OK) {
@@ -1691,14 +1609,13 @@ socket_resume_io(struct IPC_CHANNEL *ch)
cl_log(LOG_ERR
, "socket_resume_io_write() failure");
}
- }else{
+ } else {
return (OKonce ? IPC_OK : IPC_BROKEN);
}
return (rc1 != IPC_OK ? rc1 : rc2);
}
-
static int
socket_get_recv_fd(struct IPC_CHANNEL *ch)
{
@@ -1770,66 +1687,58 @@ socket_set_recv_qlen (struct IPC_CHANNEL* ch, int q_len)
return IPC_OK;
}
-
static int ipcmsg_count_allocated = 0;
static int ipcmsg_count_freed = 0;
void socket_ipcmsg_dump_stats(void);
void
-socket_ipcmsg_dump_stats(void){
-
+socket_ipcmsg_dump_stats(void) {
cl_log(LOG_INFO, "ipcsocket ipcmsg allocated=%d, freed=%d, diff=%d",
ipcmsg_count_allocated,
ipcmsg_count_freed,
ipcmsg_count_allocated - ipcmsg_count_freed);
-
- return;
-
}
static void
socket_del_ipcmsg(IPC_Message* m)
{
- if (m == NULL){
+ if (m == NULL) {
cl_log(LOG_ERR, "socket_del_ipcmsg:"
"msg is NULL");
return;
}
-
- if (m->msg_body){
+
+ if (m->msg_body) {
memset(m->msg_body, 0, m->msg_len);
}
- if (m->msg_buf){
+ if (m->msg_buf) {
g_free(m->msg_buf);
}
-
+
memset(m, 0, sizeof(*m));
g_free(m);
ipcmsg_count_freed ++;
-
- return;
}
-
static IPC_Message*
socket_new_ipcmsg(IPC_Channel* ch, const void* data, int len, void* private)
{
IPC_Message* hdr;
-
- if (ch == NULL || len < 0){
+
+ if (ch == NULL || len < 0) {
cl_log(LOG_ERR, "socket_new_ipcmsg:"
" invalid parameter");
return NULL;
}
-
- if (ch->msgpad > MAX_MSGPAD){
+
+ if (ch->msgpad > MAX_MSGPAD) {
cl_log(LOG_ERR, "socket_new_ipcmsg: too many pads "
"something is wrong");
return NULL;
}
hdr = ipcmsg_new(ch, data, len, private, socket_del_ipcmsg);
-
+
if (hdr) ipcmsg_count_allocated ++;
return hdr;
@@ -1844,26 +1753,23 @@ ipcmsg_new(struct IPC_CHANNEL * ch, const void* data, int len, void* private,
char* copy = NULL;
char* buf;
char* body;
-
+
if ((hdr = g_new(struct IPC_MESSAGE, 1)) == NULL) {
return NULL;
}
-
memset(hdr, 0, sizeof(*hdr));
-
- if (len > 0){
+
+ if (len > 0) {
if ((copy = (char*)g_malloc(ch->msgpad + len)) == NULL) {
g_free(hdr);
return NULL;
}
-
- if (data){
+ if (data) {
memcpy(copy + ch->msgpad, data, len);
}
-
buf = copy;
body = copy + ch->msgpad;;
- }else {
+ } else {
len = 0;
buf = body = NULL;
}
@@ -1873,7 +1779,7 @@ ipcmsg_new(struct IPC_CHANNEL * ch, const void* data, int len, void* private,
hdr->msg_ch = ch;
hdr->msg_done = delproc;
hdr->msg_private = private;
-
+
return hdr;
}
@@ -1891,8 +1797,7 @@ static struct IPC_WAIT_OPS socket_wait_ops = {
socket_accept_connection,
};
-
-/*
+/*
* create a new ipc queue whose length = 0 and inner queue = NULL.
* return the pointer to a new ipc queue or NULL is the queue can't be created.
*/
@@ -1901,7 +1806,7 @@ static struct IPC_QUEUE*
socket_queue_new(void)
{
struct IPC_QUEUE *temp_queue;
-
+
/* temp queue with length = 0 and inner queue = NULL. */
temp_queue = g_new(struct IPC_QUEUE, 1);
temp_queue->current_qlen = 0;
@@ -1912,31 +1817,27 @@ socket_queue_new(void)
return temp_queue;
}
-
-
-
-
-/*
+/*
* socket_wait_conn_new:
* Called by ipc_wait_conn_constructor to get a new socket
* waiting connection.
* (better explanation of this role might be nice)
- *
+ *
* Parameters :
* ch_attrs (IN) the attributes used to create this connection.
*
* Return :
* the pointer to the new waiting connection or NULL if the connection
* can't be created.
- *
+ *
* NOTE :
* for domain socket implementation, the only attribute needed is path name.
- * so the user should
- * create the hash table like this:
- * GHashTable * attrs;
- * attrs = g_hash_table_new(g_str_hash, g_str_equal);
- * g_hash_table_insert(attrs, PATH_ATTR, path_name);
- * here PATH_ATTR is defined as "path".
+ * so the user should
+ * create the hash table like this:
+ * GHashTable * attrs;
+ * attrs = g_hash_table_new(g_str_hash, g_str_equal);
+ * g_hash_table_insert(attrs, PATH_ATTR, path_name);
+ * here PATH_ATTR is defined as "path".
*
* NOTE :
* The streams implementation uses "Streams Programming Guide", Solaris 8,
@@ -1962,7 +1863,7 @@ socket_wait_conn_new(GHashTable *ch_attrs)
if (mode_attr != NULL) {
s_mode = (mode_t)strtoul((const char *)mode_attr, NULL, 8);
- }else{
+ } else {
s_mode = 0777;
}
if (path_name == NULL) {
@@ -1987,9 +1888,9 @@ socket_wait_conn_new(GHashTable *ch_attrs)
close(s);
return NULL;
}
-
+
strncpy(my_addr.sun_path, path_name, sizeof(my_addr.sun_path));
-
+
if (bind(s, (struct sockaddr *)&my_addr, sizeof(my_addr)) == -1) {
cl_perror("socket_wait_conn_new: trying to create in %s bind:"
, path_name);
@@ -2029,7 +1930,7 @@ socket_wait_conn_new(GHashTable *ch_attrs)
#endif
/* Change the permission of the socket */
- if (chmod(path_name,s_mode) < 0){
+ if (chmod(path_name,s_mode) < 0) {
cl_perror("socket_wait_conn_new: failure trying to chmod %s"
, path_name);
close(s);
@@ -2059,7 +1960,7 @@ socket_wait_conn_new(GHashTable *ch_attrs)
close(s);
return NULL;
}
-
+
wait_private = g_new(struct SOCKET_WAIT_CONN_PRIVATE, 1);
#if HB_IPC_METHOD == HB_IPC_SOCKET
wait_private->s = s;
@@ -2071,14 +1972,12 @@ socket_wait_conn_new(GHashTable *ch_attrs)
temp_ch = g_new(struct IPC_WAIT_CONNECTION, 1);
temp_ch->ch_private = (void *) wait_private;
temp_ch->ch_status = IPC_WAIT;
- temp_ch->ops = (struct IPC_WAIT_OPS *)&socket_wait_ops;
+ temp_ch->ops = (struct IPC_WAIT_OPS *)&socket_wait_ops;
return temp_ch;
}
-
-
-/*
+/*
* will be called by ipc_channel_constructor to create a new socket channel.
* parameters :
* attrs (IN) the hash table of the attributes used to create this channel.
@@ -2087,7 +1986,7 @@ socket_wait_conn_new(GHashTable *ch_attrs)
* the pointer to the new waiting channel or NULL if the channel can't be created.
*/
-struct IPC_CHANNEL *
+struct IPC_CHANNEL *
socket_client_channel_new(GHashTable *ch_attrs) {
char *path_name;
int sockfd;
@@ -2101,7 +2000,7 @@ socket_client_channel_new(GHashTable *ch_attrs) {
*
* Maybe we need an internal function with a different set of parameters?
*/
-
+
/*
* if we want to seperate them. I suggest
* <client side>
@@ -2132,13 +2031,11 @@ socket_client_channel_new(GHashTable *ch_attrs) {
return NULL;
}
#endif
-
+
if (client_channel_new_auth(sockfd) < 0) {
close(sockfd);
return NULL;
}
-
-
return channel_new(sockfd, IPC_CLIENT, path_name);
}
@@ -2156,10 +2053,10 @@ int client_channel_new_auth(int sockfd) {
/* make sure socket paths never clash */
uuid_generate(rand_id);
uuid_unparse(rand_id, uuid_str_tmp);
-
+
snprintf(sock_addr.sun_path, sizeof(sock_addr.sun_path),
"%s/%s", HA_VARLIBHBDIR, uuid_str_tmp);
-
+
unlink(sock_addr.sun_path);
if(bind(sockfd, (struct sockaddr*)&sock_addr, SUN_LEN(&sock_addr)) < 0) {
perror("Client bind() failure");
@@ -2171,31 +2068,31 @@ int client_channel_new_auth(int sockfd) {
}
static
-struct IPC_CHANNEL *
+struct IPC_CHANNEL *
socket_server_channel_new(int sockfd) {
return channel_new(sockfd, IPC_SERVER, "?");
}
static
-struct IPC_CHANNEL *
+struct IPC_CHANNEL *
channel_new(int sockfd, int conntype, const char *path_name) {
struct IPC_CHANNEL * temp_ch;
struct SOCKET_CH_PRIVATE* conn_info;
int flags;
-
+
if (path_name == NULL || strlen(path_name) >= sizeof(conn_info->path_name)) {
return NULL;
}
-
- temp_ch = g_new(struct IPC_CHANNEL, 1);
- if (temp_ch == NULL){
+
+ temp_ch = g_new(struct IPC_CHANNEL, 1);
+ if (temp_ch == NULL) {
cl_log(LOG_ERR, "channel_new: allocating memory for channel failed");
- return NULL;
+ return NULL;
}
memset(temp_ch, 0, sizeof(struct IPC_CHANNEL));
-
+
conn_info = g_new(struct SOCKET_CH_PRIVATE, 1);
-
+
flags = fcntl(sockfd, F_GETFL);
if (flags == -1) {
cl_perror("channel_new: cannot read file descriptor flags");
@@ -2242,7 +2139,6 @@ channel_new(int sockfd, int conntype, const char *path_name) {
temp_ch->farside_gid = -1;
return temp_ch;
-
}
/*
@@ -2303,39 +2199,31 @@ ipc_channel_pair(IPC_Channel* channels[2])
channels[j]->farside_pid = getpid();
strncpy(p->path_name, pname, sizeof(p->path_name));
}
-
+
return IPC_OK;
-
}
-
/* brief free the memory space allocated to msg and destroy msg. */
-
static void
socket_free_message(struct IPC_MESSAGE * msg) {
-
#if 0
memset(msg->msg_body, 0xff, msg->msg_len);
#endif
-
- if (msg->msg_buf){
+ if (msg->msg_buf) {
g_free(msg->msg_buf);
- }else {
+ } else {
g_free(msg->msg_body);
}
-
#if 0
memset(msg, 0xff, sizeof(*msg));
#endif
g_free((void *)msg);
}
-
-
-/*
- * create a new ipc message whose msg_body's length is msg_len.
- *
+/*
+ * create a new ipc message whose msg_body's length is msg_len.
+ *
* parameters :
* msg_len (IN) the length of this message body in this message.
*
@@ -2349,7 +2237,6 @@ socket_message_new(struct IPC_CHANNEL *ch, int msg_len)
return ipcmsg_new(ch, NULL, msg_len, NULL, socket_free_message);
}
-
/***********************************************************************
*
* IPC authentication schemes... More machine dependent than
@@ -2369,7 +2256,7 @@ verify_creds(struct IPC_AUTH *auth_info, uid_t uid, gid_t gid)
&& (g_hash_table_lookup(auth_info->uid
, GUINT_TO_POINTER((guint)uid)) != NULL)) {
ret = IPC_OK;
- }else if (auth_info->gid
+ } else if (auth_info->gid
&& (g_hash_table_lookup(auth_info->gid
, GUINT_TO_POINTER((guint)gid)) != NULL)) {
ret = IPC_OK;
@@ -2377,21 +2264,20 @@ verify_creds(struct IPC_AUTH *auth_info, uid_t uid, gid_t gid)
return ret;
}
-
/***********************************************************************
* SO_PEERCRED VERSION... (Linux)
***********************************************************************/
#ifdef USE_SO_PEERCRED
/* verify the authentication information. */
-static int
+static int
socket_verify_auth(struct IPC_CHANNEL* ch, struct IPC_AUTH * auth_info)
{
struct SOCKET_CH_PRIVATE * conn_info;
int ret = IPC_FAIL;
struct ucred cred;
socklen_t n = sizeof(cred);
-
+
if (ch == NULL || ch->ch_private == NULL) {
return IPC_FAIL;
}
@@ -2421,8 +2307,6 @@ socket_verify_auth(struct IPC_CHANNEL* ch, struct IPC_AUTH * auth_info)
, (unsigned long)auth_info->uid
, (unsigned long)auth_info->gid);
#endif
-
-
/* verify the credential information. */
return verify_creds(auth_info, cred.uid, cred.gid);
}
@@ -2433,19 +2317,18 @@ static
pid_t
socket_get_farside_pid(int sockfd)
{
-
socklen_t n;
struct ucred *cred;
pid_t f_pid;
-
+
/* Get the credential information from peer */
n = sizeof(struct ucred);
- cred = g_new(struct ucred, 1);
+ cred = g_new(struct ucred, 1);
if (getsockopt(sockfd, SOL_SOCKET, SO_PEERCRED, cred, &n) != 0) {
g_free(cred);
return -1;
}
-
+
f_pid = cred->pid;
g_free(cred);
return f_pid;
@@ -2462,7 +2345,7 @@ socket_get_farside_pid(int sockfd)
* as a replacement library. That would simplify things...
*/
-static int
+static int
socket_verify_auth(struct IPC_CHANNEL* ch, struct IPC_AUTH * auth_info)
{
struct SOCKET_CH_PRIVATE *conn_info;
@@ -2504,11 +2387,11 @@ socket_get_farside_pid(int sock)
* This isn't an emergency, but should be done in the future...
* Hint: * Postgresql does both types of authentication...
* see src/backend/libpq/auth.c
- * Not clear its SO_PEERCRED implementation works though ;-)
+ * Not clear its SO_PEERCRED implementation works though ;-)
*/
/* Done.... Haven't tested yet. */
-static int
+static int
socket_verify_auth(struct IPC_CHANNEL* ch, struct IPC_AUTH * auth_info)
{
struct msghdr msg;
@@ -2572,7 +2455,7 @@ socket_verify_auth(struct IPC_CHANNEL* ch, struct IPC_AUTH * auth_info)
struct SOCKET_CH_PRIVATE *conn_info;
int ret = IPC_FAIL;
char buf;
-
+
/* Compute size without padding */
#define CMSGSIZE (sizeof(struct cmsghdr)+(sizeof(Cred))+EXTRASPACE)
@@ -2585,7 +2468,6 @@ socket_verify_auth(struct IPC_CHANNEL* ch, struct IPC_AUTH * auth_info)
/* Point to start of first structure */
struct cmsghdr *cmsg = &cmsgmem.hdr;
-
if (auth_info == NULL
|| (auth_info->uid == NULL && auth_info->gid == NULL)) {
@@ -2607,8 +2489,8 @@ socket_verify_auth(struct IPC_CHANNEL* ch, struct IPC_AUTH * auth_info)
*/
msg.msg_iov->iov_base = &buf;
msg.msg_iov->iov_len = 1;
-
- if (recvmsg(conn_info->s, &msg, 0) < 0
+
+ if (recvmsg(conn_info->s, &msg, 0) < 0
|| cmsg->cmsg_len < CMSGSIZE
|| cmsg->cmsg_type != SCM_CREDS) {
cl_perror("can't get credential information from peer");
@@ -2631,7 +2513,7 @@ socket_verify_auth(struct IPC_CHANNEL* ch, struct IPC_AUTH * auth_info)
/*
* FIXME! Need to implement SCM_CREDS mechanism for BSD-based systems
* this is similar to the SCM_CREDS mechanism for verify_auth() function.
- * here we just want to get the pid of the other side from the credential
+ * here we just want to get the pid of the other side from the credential
* information.
*/
@@ -2644,7 +2526,6 @@ socket_get_farside_pid(int sock)
}
#endif /* SCM_CREDS version */
-
/***********************************************************************
* Bind/Stat VERSION... (Supported on OSX/Darwin and 4.3+BSD at least...)
*
@@ -2657,26 +2538,26 @@ socket_get_farside_pid(int sock)
*/
#ifdef USE_BINDSTAT_CREDS
-static int
+static int
socket_verify_auth(struct IPC_CHANNEL* ch, struct IPC_AUTH * auth_info)
{
int len = 0;
int ret = IPC_FAIL;
struct stat stat_buf;
struct sockaddr_un *peer_addr = NULL;
- struct SOCKET_CH_PRIVATE *ch_private = NULL;
+ struct SOCKET_CH_PRIVATE *ch_private = NULL;
if(ch != NULL) {
ch_private = (struct SOCKET_CH_PRIVATE *)(ch->ch_private);
if(ch_private != NULL) {
- peer_addr = ch_private->peer_addr;
+ peer_addr = ch_private->peer_addr;
}
}
if(ch == NULL) {
cl_log(LOG_ERR, "No channel to authenticate");
return IPC_FAIL;
-
+
} else if (auth_info == NULL
|| (auth_info->uid == NULL && auth_info->gid == NULL)) {
ret = IPC_OK; /* no restriction for authentication */
@@ -2686,12 +2567,12 @@ socket_verify_auth(struct IPC_CHANNEL* ch, struct IPC_AUTH * auth_info)
if(ch_private == NULL) {
cl_log(LOG_ERR, "No channel private data available");
return ret;
-
- } else if(peer_addr == NULL) {
+
+ } else if(peer_addr == NULL) {
cl_log(LOG_ERR, "No peer information available");
return ret;
}
-
+
len = SUN_LEN(peer_addr);
if(len < 1) {
@@ -2720,9 +2601,7 @@ socket_verify_auth(struct IPC_CHANNEL* ch, struct IPC_AUTH * auth_info)
return verify_creds(auth_info, stat_buf.st_uid, stat_buf.st_gid);
}
-
-static
-pid_t
+static pid_t
socket_get_farside_pid(int sock)
{
return -1;
@@ -2733,7 +2612,7 @@ socket_get_farside_pid(int sock)
* USE_STREAM_CREDS VERSION... (e.g. Solaris pre-10)
***********************************************************************/
#ifdef USE_STREAM_CREDS
-static int
+static int
socket_verify_auth(struct IPC_CHANNEL* ch, struct IPC_AUTH * auth_info)
{
struct SOCKET_CH_PRIVATE *conn_info;
@@ -2766,7 +2645,7 @@ socket_get_farside_pid(int sock)
#ifdef USE_GETPEERUCRED
/* verify the authentication information. */
-static int
+static int
socket_verify_auth(struct IPC_CHANNEL* ch, struct IPC_AUTH * auth_info)
{
struct SOCKET_CH_PRIVATE *conn_info;
@@ -2839,7 +2718,7 @@ socket_get_farside_pid(int sockfd)
***********************************************************************/
#ifdef USE_DUMMY_CREDS
-static int
+static int
socket_verify_auth(struct IPC_CHANNEL* ch, struct IPC_AUTH * auth_info)
{
return IPC_FAIL;
@@ -2853,8 +2732,6 @@ socket_get_farside_pid(int sock)
}
#endif /* Dummy version */
-
-
/* socket object of the function table */
static struct IPC_OPS socket_ops = {
socket_destroy_channel,
diff --git a/lib/clplumbing/ipctest.c b/lib/clplumbing/ipctest.c
index a8f7999..333d3a0 100644
--- a/lib/clplumbing/ipctest.c
+++ b/lib/clplumbing/ipctest.c
@@ -394,7 +394,7 @@ transport_tests(int iterations, int clients)
return rc;
}
-static int data_size = 10;
+static int data_size = 20;
int
main(int argc, char ** argv)
@@ -438,6 +438,10 @@ main(int argc, char ** argv)
fprintf(stderr, "data size must be >=0\n");
argerrs++;
}
+ if (data_size > MAXMSG) {
+ fprintf(stderr, "maximum data size is %d\n", MAXMSG);
+ argerrs++;
+ }
break;
default:
argerrs++;
@@ -450,7 +454,7 @@ main(int argc, char ** argv)
"\t-v : verbose\n"
"\t-i : iterations (default %d)\n"
"\t-c : number of clients (default %d; nonzero invokes client/server)\n"
- "\t-s : data size (default 10 bytes)\n",
+ "\t-s : data size (default 20 bytes)\n",
procname, iter_def, clients_def);
exit(1);
}
@@ -560,7 +564,10 @@ echoserver(IPC_Channel* wchan, int repcount)
IPC_Message wmsg;
IPC_Message* rmsg = NULL;
- str = malloc(data_size);
+ if (!(str = malloc(data_size))) {
+ cl_log(LOG_ERR, "Out of memory");
+ exit(1);
+ }
memset(&wmsg, 0, sizeof(wmsg));
wmsg.msg_private = NULL;
@@ -1205,7 +1212,10 @@ checkmsg(IPC_Message* rmsg, const char * who, int rcount)
char *str;
size_t len;
- str = malloc(data_size);
+ if (!(str = malloc(data_size))) {
+ cl_log(LOG_ERR, "Out of memory");
+ exit(1);
+ }
echomsgbody(str, data_size, rcount, &len);
diff --git a/lib/clplumbing/ocf_ipc.c b/lib/clplumbing/ocf_ipc.c
index 679cdbb..28c168c 100644
--- a/lib/clplumbing/ocf_ipc.c
+++ b/lib/clplumbing/ocf_ipc.c
@@ -9,12 +9,12 @@
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
- *
+ *
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
- *
+ *
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
@@ -42,7 +42,6 @@ void cl_log_message (int log_level, const struct ha_msg *m);
int timediff(longclock_t t1, longclock_t t2);
void ha_msg_del(struct ha_msg* msg);
void ipc_time_debug(IPC_Channel* ch, IPC_Message* ipcmsg, int whichpos);
-
#endif
struct IPC_WAIT_CONNECTION * socket_wait_conn_new(GHashTable* ch_attrs);
@@ -58,7 +57,7 @@ ipc_set_pollfunc(int (*pf)(struct pollfd*, unsigned int, int))
ipc_pollfunc_ptr = pf;
}
-struct IPC_WAIT_CONNECTION *
+struct IPC_WAIT_CONNECTION *
ipc_wait_conn_constructor(const char * ch_type, GHashTable* ch_attrs)
{
if (strcmp(ch_type, "domain_socket") == 0
@@ -70,7 +69,7 @@ ipc_wait_conn_constructor(const char * ch_type, GHashTable* ch_attrs)
return NULL;
}
-struct IPC_CHANNEL *
+struct IPC_CHANNEL *
ipc_channel_constructor(const char * ch_type, GHashTable* ch_attrs)
{
if (strcmp(ch_type, "domain_socket") == 0
@@ -82,6 +81,7 @@ ipc_channel_constructor(const char * ch_type, GHashTable* ch_attrs)
}
return NULL;
}
+
static int
gnametonum(const char * gname, int gnlen)
{
@@ -97,7 +97,7 @@ gnametonum(const char * gname, int gnlen)
strncpy(grpname, gname, gnlen);
grpname[gnlen] = EOS;
if ((grp = getgrnam(grpname)) == NULL) {
- cl_log(LOG_ERR
+ cl_log(LOG_ERR
, "Invalid group name [%s]", grpname);
return -1;
}
@@ -111,7 +111,7 @@ unametonum(const char * lname, int llen)
struct passwd* pwd;
if (llen >= (int)sizeof(loginname)) {
- cl_log(LOG_ERR
+ cl_log(LOG_ERR
, "user id name [%s] is too long", loginname);
return -1;
}
@@ -122,7 +122,7 @@ unametonum(const char * lname, int llen)
return atoi(loginname);
}
if ((pwd = getpwnam(loginname)) == NULL) {
- cl_log(LOG_ERR
+ cl_log(LOG_ERR
, "Invalid user id name [%s]", loginname);
return -1;
}
@@ -166,21 +166,19 @@ make_id_table(const char * list, int listlen, int (*map)(const char *, int))
return ret;
}
-
-
struct IPC_AUTH*
ipc_str_to_auth(const char* uidlist, int uidlen, const char* gidlist, int gidlen)
{
struct IPC_AUTH* auth;
-
+
auth = malloc(sizeof(struct IPC_AUTH));
if (auth == NULL) {
cl_log(LOG_ERR, "Out of memory for IPC_AUTH");
return NULL;
}
-
+
memset(auth, 0, sizeof(*auth));
-
+
if (uidlist) {
auth->uid = make_id_table(uidlist, uidlen, unametonum);
if (auth->uid == NULL) {
@@ -199,28 +197,23 @@ ipc_str_to_auth(const char* uidlist, int uidlen, const char* gidlist, int gidlen
goto errout;
}
}
-
-
return auth;
-
+
errout:
- if (auth->uid){
+ if (auth->uid) {
g_hash_table_destroy(auth->uid);
- auth->uid = NULL;
+ auth->uid = NULL;
}
-
- if (auth->gid){
+ if (auth->gid) {
g_hash_table_destroy(auth->gid);
- auth->gid = NULL;
+ auth->gid = NULL;
}
-
free(auth);
auth = NULL;
return NULL;
-
}
-struct IPC_AUTH *
+struct IPC_AUTH *
ipc_set_auth(uid_t * a_uid, gid_t * a_gid, int num_uid, int num_gid)
{
struct IPC_AUTH *temp_auth;
@@ -228,7 +221,7 @@ ipc_set_auth(uid_t * a_uid, gid_t * a_gid, int num_uid, int num_gid)
static int v = 1;
temp_auth = malloc(sizeof(struct IPC_AUTH));
- if (temp_auth == NULL){
+ if (temp_auth == NULL) {
cl_log(LOG_ERR, "%s: memory allocation failed",__FUNCTION__);
return NULL;
}
@@ -266,178 +259,154 @@ ipc_destroy_auth(struct IPC_AUTH *auth)
}
}
-static void
+static void
ipc_bufpool_display(struct ipc_bufpool* pool)
{
-
- if (pool == NULL){
- cl_log(LOG_ERR, "pool is NULL");
+ if (pool == NULL) {
return;
}
-
-
cl_log(LOG_INFO, "pool: refcount=%d, startpos=%p, currpos=%p,"
- "consumepos=%p, endpos=%p, size=%d",
- pool->refcount,
- pool->startpos,
- pool->currpos,
- pool->consumepos,
- pool->endpos,
- pool->size);
+ "consumepos=%p, endpos=%p, size=%d",
+ pool->refcount, pool->startpos,
+ pool->currpos, pool->consumepos,
+ pool->endpos, pool->size);
}
-void ipc_bufpool_dump_stats(void);
void
ipc_bufpool_dump_stats(void)
{
- cl_log(LOG_INFO, "num_pool_allocated=%d, num_pool_freed=%d, diff=%d",
- num_pool_allocated,
- num_pool_freed,
+ cl_log(LOG_INFO, "num_pool_allocated=%d, num_pool_freed=%d, diff=%d",
+ num_pool_allocated,
+ num_pool_freed,
num_pool_allocated - num_pool_freed);
- return;
-
}
+#define POOLHDR_SIZE \
+ (sizeof(struct ipc_bufpool) + 2*sizeof(struct SOCKET_MSG_HEAD))
+
struct ipc_bufpool*
ipc_bufpool_new(int size)
{
struct ipc_bufpool* pool;
int totalsize;
-
-
+
/* there are memories for two struct SOCKET_MSG_HEAD
* one for the big message, the other one for the next
- * message. This code prevents allocating
- * <big memory> <4k> <big memory><4k> ...
+ * message. This code prevents allocating
+ * <big memory> <4k> <big memory><4k> ...
* from happening when a client sends big messages
* constantly*/
- totalsize = size + sizeof(struct ipc_bufpool)
- + sizeof(struct SOCKET_MSG_HEAD) * 2 ;
-
- if (totalsize < POOL_SIZE){
+ totalsize = size + POOLHDR_SIZE;
+
+ if (totalsize < POOL_SIZE) {
totalsize = POOL_SIZE;
}
-
- if (totalsize > MAXMSG){
+
+ if (totalsize > MAXMSG + POOLHDR_SIZE) {
cl_log(LOG_INFO, "ipc_bufpool_new: "
- "asking for buffer with size %d"
+ "asking for buffer with size %d; "
"corrupted data len???", totalsize);
return NULL;
}
-
+
pool = (struct ipc_bufpool*)malloc(totalsize+1);
- if (pool == NULL){
+ if (pool == NULL) {
cl_log(LOG_ERR, "%s: memory allocation failed", __FUNCTION__);
return NULL;
}
memset(pool, 0, totalsize);
pool->refcount = 1;
pool->startpos = pool->currpos = pool->consumepos =
- ((char*)pool) + sizeof(struct ipc_bufpool);
-
+ ((char*)pool) + sizeof(struct ipc_bufpool);
+
pool->endpos = ((char*)pool) + totalsize;
pool->size = totalsize;
-
+
num_pool_allocated ++ ;
-
+
return pool;
}
void
ipc_bufpool_del(struct ipc_bufpool* pool)
{
-
- if (pool == NULL){
+ if (pool == NULL) {
return;
}
-
- if (pool->refcount > 0){
+
+ if (pool->refcount > 0) {
cl_log(LOG_ERR," ipc_bufpool_del:"
- " IPC buffer pool reference count"
- " > 0");
+ " IPC buffer pool reference count > 0");
return;
}
-
+
memset(pool, 0, pool->size);
- free(pool);
+ free(pool);
num_pool_freed ++ ;
- return;
}
int
ipc_bufpool_spaceleft(struct ipc_bufpool* pool)
{
-
- if( pool == NULL){
- cl_log(LOG_ERR, "ipc_bufpool_spacelft:"
- "invalid input argument");
- return 0;
+ if( pool == NULL) {
+ cl_log(LOG_ERR, "ipc_bufpool_spaceleft:"
+ " invalid input argument");
+ return 0;
}
-
return pool->endpos - pool->currpos;
}
-
-
-
/* brief free the memory space allocated to msg and destroy msg. */
static void
-ipc_bufpool_msg_done(struct IPC_MESSAGE * msg) {
-
+ipc_bufpool_msg_done(struct IPC_MESSAGE * msg)
+{
struct ipc_bufpool* pool;
-
- if (msg == NULL){
- cl_log(LOG_ERR, "ipc_bufpool_msg_done:"
- "invalid input");
+
+ if (msg == NULL) {
+ cl_log(LOG_ERR, "ipc_bufpool_msg_done: invalid input");
return;
}
-
+
pool = (struct ipc_bufpool*)msg->msg_private;
-
+
ipc_bufpool_unref(pool);
free(msg);
-
}
static struct IPC_MESSAGE*
ipc_bufpool_msg_new(void)
{
struct IPC_MESSAGE * temp_msg;
-
+
temp_msg = malloc(sizeof(struct IPC_MESSAGE));
- if (temp_msg == NULL){
+ if (temp_msg == NULL) {
cl_log(LOG_ERR, "ipc_bufpool_msg_new:"
"allocating new msg failed");
return NULL;
}
-
+
memset(temp_msg, 0, sizeof(struct IPC_MESSAGE));
return temp_msg;
}
-
static void
ipcmsg_display(IPC_Message* ipcmsg)
{
- if (ipcmsg == NULL){
+ if (ipcmsg == NULL) {
cl_log(LOG_ERR, "ipcmsg is NULL");
return;
}
-
cl_log(LOG_INFO, "ipcmsg: msg_len=%lu, msg_buf=%p, msg_body=%p,"
"msg_done=%p, msg_private=%p, msg_ch=%p",
(unsigned long)ipcmsg->msg_len,
- ipcmsg->msg_buf,
+ ipcmsg->msg_buf,
ipcmsg->msg_body,
ipcmsg->msg_done,
ipcmsg->msg_private,
ipcmsg->msg_ch);
-
- return;
-
}
/* after a recv call, we have new data
@@ -456,25 +425,24 @@ ipc_bufpool_update(struct ipc_bufpool* pool,
struct SOCKET_MSG_HEAD localhead;
struct SOCKET_MSG_HEAD* head = &localhead;
int nmsgs = 0 ;
-
- if (rqueue == NULL){
+ if (rqueue == NULL) {
cl_log(LOG_ERR, "ipc_update_bufpool:"
"invalid input");
return 0;
}
-
+
pool->currpos += msg_len;
-
- while(TRUE){
+
+ while(TRUE) {
/*not enough data for head*/
- if ((int)(pool->currpos - pool->consumepos) < (int)ch->msgpad){
+ if ((int)(pool->currpos - pool->consumepos) < (int)ch->msgpad) {
break;
}
-
+
memcpy(head, pool->consumepos, sizeof(struct SOCKET_MSG_HEAD));
-
- if (head->magic != HEADMAGIC){
+
+ if (head->magic != HEADMAGIC) {
GList* last = g_list_last(rqueue->queue);
cl_log(LOG_ERR, "ipc_bufpool_update: "
"magic number in head does not match."
@@ -484,99 +452,84 @@ ipc_bufpool_update(struct ipc_bufpool* pool,
ipc_bufpool_display(pool);
cl_log(LOG_INFO, "nmsgs=%d", nmsgs);
/*print out the last message in queue*/
- if (last){
+ if (last) {
IPC_Message* m = (IPC_Message*)last;
ipcmsg_display(m);
}
abort();
}
- if ( head->msg_len > MAXMSG){
+ if ( head->msg_len > MAXMSG) {
cl_log(LOG_ERR, "ipc_update_bufpool:"
"msg length is corruptted(%d)",
head->msg_len);
break;
}
-
+
if (pool->consumepos + ch->msgpad + head->msg_len
- > pool->currpos){
- break;
+ > pool->currpos) {
+ break;
}
-
+
ipcmsg = ipc_bufpool_msg_new();
- if (ipcmsg == NULL){
+ if (ipcmsg == NULL) {
cl_log(LOG_ERR, "ipc_update_bufpool:"
"allocating memory for new ipcmsg failed");
break;
-
+
}
ipcmsg->msg_buf = pool->consumepos;
ipcmsg->msg_body = pool->consumepos + ch->msgpad;
ipcmsg->msg_len = head->msg_len;
ipcmsg->msg_private = pool;
ipcmsg->msg_done = ipc_bufpool_msg_done;
-
-#ifdef IPC_TIME_DEBUG
+#ifdef IPC_TIME_DEBUG
ipc_time_debug(ch,ipcmsg, MSGPOS_RECV);
-#endif
-
-
+#endif
rqueue->queue = g_list_append(rqueue->queue, ipcmsg);
rqueue->current_qlen ++;
nmsgs++;
-
+
pool->consumepos += ch->msgpad + head->msg_len;
ipc_bufpool_ref(pool);
}
-
return nmsgs;
}
-
-
-
-
-
gboolean
-ipc_bufpool_full(struct ipc_bufpool* pool,
- struct IPC_CHANNEL* ch,
+ipc_bufpool_full(struct ipc_bufpool* pool,
+ struct IPC_CHANNEL* ch,
int* dataspaceneeded)
{
-
struct SOCKET_MSG_HEAD localhead;
struct SOCKET_MSG_HEAD* head = &localhead;
*dataspaceneeded = 0;
/* not enough space for head */
- if ((int)(pool->endpos - pool->consumepos) < (int)ch->msgpad){
+ if ((int)(pool->endpos - pool->consumepos) < (int)ch->msgpad) {
return TRUE;
}
-
+
/*enough space for head*/
- if ((int)(pool->currpos - pool->consumepos) >= (int)ch->msgpad){
+ if ((int)(pool->currpos - pool->consumepos) >= (int)ch->msgpad) {
memcpy(head, pool->consumepos, sizeof(struct SOCKET_MSG_HEAD));
-
+
/* not enough space for data*/
- if ( pool->consumepos + ch->msgpad + head->msg_len >= pool->endpos){
+ if ( pool->consumepos + ch->msgpad + head->msg_len >= pool->endpos) {
*dataspaceneeded = head->msg_len;
return TRUE;
}
}
-
-
- /* Either we are sure we have enough space
+
+ /* Either we are sure we have enough space
* or we cannot tell because we have not received
* head yet. But we are sure we have enough space
* for head
*/
return FALSE;
-
-
-
}
-
-int
+int
ipc_bufpool_partial_copy(struct ipc_bufpool* dstpool,
struct ipc_bufpool* srcpool)
{
@@ -584,66 +537,58 @@ ipc_bufpool_partial_copy(struct ipc_bufpool* dstpool,
struct SOCKET_MSG_HEAD *head = &localhead;
int space_needed;
int nbytes;
-
+
if (dstpool == NULL
- || srcpool == NULL){
+ || srcpool == NULL) {
cl_log(LOG_ERR, "ipc_bufpool_partial_ipcmsg_cp:"
- "invalid input");
+ "invalid input");
return IPC_FAIL;
}
-
+
if (srcpool->currpos - srcpool->consumepos >=
- (ssize_t)sizeof(struct SOCKET_MSG_HEAD)){
-
+ (ssize_t)sizeof(struct SOCKET_MSG_HEAD)) {
+
memcpy(head, srcpool->consumepos, sizeof(struct SOCKET_MSG_HEAD));
space_needed = head->msg_len + sizeof(*head);
-
- if (space_needed > ipc_bufpool_spaceleft(dstpool)){
+
+ if (space_needed > ipc_bufpool_spaceleft(dstpool)) {
cl_log(LOG_ERR, "ipc_bufpool_partial_ipcmsg_cp:"
" not enough space left in dst pool,spaced needed=%d",
space_needed);
- return IPC_FAIL;
- }
+ return IPC_FAIL;
+ }
}
-
+
nbytes = srcpool->currpos - srcpool->consumepos;
memcpy(dstpool->consumepos, srcpool->consumepos,nbytes);
-
-
+
srcpool->currpos = srcpool->consumepos;
dstpool->currpos = dstpool->consumepos + nbytes;
-
+
return IPC_OK;
}
-
void
ipc_bufpool_ref(struct ipc_bufpool* pool)
{
- if (pool == NULL){
+ if (pool == NULL) {
cl_log(LOG_ERR, "ref_pool:"
" invalid input");
- return;
+ return;
}
-
pool->refcount ++;
-
}
void
-ipc_bufpool_unref(struct ipc_bufpool* pool){
-
- if (pool == NULL){
+ipc_bufpool_unref(struct ipc_bufpool* pool)
+{
+ if (pool == NULL) {
cl_log(LOG_ERR, "unref_pool:"
" invalid input");
- return;
+ return;
}
-
pool->refcount --;
-
- if (pool->refcount <= 0){
+ if (pool->refcount <= 0) {
ipc_bufpool_del(pool);
}
-
- return;
}
diff --git a/lib/plugins/Makefile.am b/lib/plugins/Makefile.am
index 139d6f3..21827cd 100644
--- a/lib/plugins/Makefile.am
+++ b/lib/plugins/Makefile.am
@@ -17,4 +17,4 @@
#
MAINTAINERCLEANFILES = Makefile.in
-SUBDIRS = InterfaceMgr stonith lrm
+SUBDIRS = InterfaceMgr stonith lrm compress
diff --git a/lib/plugins/compress/Makefile.am b/lib/plugins/compress/Makefile.am
new file mode 100644
index 0000000..3a3193a
--- /dev/null
+++ b/lib/plugins/compress/Makefile.am
@@ -0,0 +1,52 @@
+#
+# InterfaceMgr: Interface manager plugins for Linux-HA
+#
+# Copyright (C) 2001 Alan Robertson
+#
+# 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.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+MAINTAINERCLEANFILES = Makefile.in
+
+if BUILD_ZLIB_COMPRESS_MODULE
+zlibmodule = zlib.la
+endif
+
+if BUILD_BZ2_COMPRESS_MODULE
+bz2module = bz2.la
+endif
+
+SUBDIRS =
+
+INCLUDES = -I$(top_builddir)/include -I$(top_srcdir)/include \
+ -I$(top_builddir)/linux-ha -I$(top_srcdir)/linux-ha \
+ -I$(top_builddir)/libltdl -I$(top_srcdir)/libltdl \
+ -I$(top_builddir)/lib/upmls -I$(top_srcdir)/lib/upmls
+
+AM_CFLAGS = @CFLAGS@
+
+## libraries
+
+halibdir = $(libdir)/@HB_PKG@
+plugindir = $(halibdir)/plugins/compress
+plugin_LTLIBRARIES = $(zlibmodule) $(bz2module)
+
+zlib_la_SOURCES = zlib.c
+zlib_la_LDFLAGS = -export-dynamic -module -avoid-version -lz
+zlib_la_LIBADD = $(top_builddir)/replace/libreplace.la
+
+bz2_la_SOURCES = bz2.c
+bz2_la_LDFLAGS = -export-dynamic -module -avoid-version -lbz2
+bz2_la_LIBADD = $(top_builddir)/replace/libreplace.la
+
diff --git a/lib/plugins/compress/bz2.c b/lib/plugins/compress/bz2.c
new file mode 100644
index 0000000..2eab116
--- /dev/null
+++ b/lib/plugins/compress/bz2.c
@@ -0,0 +1,142 @@
+ /* bz2.c: compression module using bz2 for heartbeat.
+ *
+ * Copyright (C) 2005 Guochun Shi <gshi at ncsa.uiuc.edu>
+ *
+ * SECURITY NOTE: It would be very easy for someone to masquerade as the
+ * device that you're pinging. If they don't know the password, all they can
+ * do is echo back the packets that you're sending out, or send out old ones.
+ * This does mean that if you're using such an approach, that someone could
+ * make you think you have quorum when you don't during a cluster partition.
+ * The danger in that seems small, but you never know ;-)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+
+
+#define PIL_PLUGINTYPE HB_COMPRESS_TYPE
+#define PIL_PLUGINTYPE_S HB_COMPRESS_TYPE_S
+#define PIL_PLUGIN bz2
+#define PIL_PLUGIN_S "bz2"
+#define PIL_PLUGINLICENSE LICENSE_LGPL
+#define PIL_PLUGINLICENSEURL URL_LGPL
+#include <lha_internal.h>
+#include <stdio.h>
+#include <pils/plugin.h>
+#include <compress.h>
+#include <bzlib.h>
+#include <clplumbing/cl_log.h>
+#include <string.h>
+
+
+static struct hb_compress_fns bz2Ops;
+
+PIL_PLUGIN_BOILERPLATE2("1.0", Debug)
+
+static const PILPluginImports* PluginImports;
+static PILPlugin* OurPlugin;
+static PILInterface* OurInterface;
+static struct hb_media_imports* OurImports;
+static void* interfprivate;
+
+#define LOG PluginImports->log
+#define MALLOC PluginImports->alloc
+#define STRDUP PluginImports->mstrdup
+#define FREE PluginImports->mfree
+
+PIL_rc
+PIL_PLUGIN_INIT(PILPlugin*us, const PILPluginImports* imports);
+
+PIL_rc
+PIL_PLUGIN_INIT(PILPlugin*us, const PILPluginImports* imports)
+{
+ /* Force the compiler to do a little type checking */
+ (void)(PILPluginInitFun)PIL_PLUGIN_INIT;
+
+ PluginImports = imports;
+ OurPlugin = us;
+
+ /* Register ourself as a plugin */
+ imports->register_plugin(us, &OurPIExports);
+
+ /* Register our interface implementation */
+ return imports->register_interface(us, PIL_PLUGINTYPE_S
+ , PIL_PLUGIN_S
+ , &bz2Ops
+ , NULL /*close */
+ , &OurInterface
+ , (void*)&OurImports
+ , interfprivate);
+}
+
+static int
+bz2_compress(char* dest, size_t* destlen,
+ const char* _src, size_t srclen)
+{
+ int ret;
+ char* src;
+ unsigned int tmpdestlen;
+
+ memcpy(&src, &_src, sizeof(char*));
+
+ tmpdestlen = *destlen;
+ ret = BZ2_bzBuffToBuffCompress(dest, &tmpdestlen, src, srclen, 1, 0, 30);
+ if (ret != BZ_OK){
+ cl_log(LOG_ERR, "%s: compression failed",
+ __FUNCTION__);
+ return HA_FAIL;
+ }
+
+ *destlen = tmpdestlen;
+
+ return HA_OK;
+}
+
+static int
+bz2_decompress(char* dest, size_t* destlen,
+ const char* _src, size_t srclen)
+{
+
+ int ret;
+ char* src;
+ unsigned int tmpdestlen;
+
+ memcpy(&src, &_src, sizeof(char*));
+
+ tmpdestlen = *destlen;
+ ret = BZ2_bzBuffToBuffDecompress(dest, &tmpdestlen, src, srclen, 1, 0);
+ if (ret != BZ_OK){
+ cl_log(LOG_ERR, "%s: decompression failed",
+ __FUNCTION__);
+ return HA_FAIL;
+ }
+
+ *destlen = tmpdestlen;
+
+ return HA_OK;
+}
+
+static const char*
+bz2_getname(void)
+{
+ return "bz2";
+}
+
+static struct hb_compress_fns bz2Ops ={
+ bz2_compress,
+ bz2_decompress,
+ bz2_getname,
+};
diff --git a/lib/plugins/compress/zlib.c b/lib/plugins/compress/zlib.c
new file mode 100644
index 0000000..5958966
--- /dev/null
+++ b/lib/plugins/compress/zlib.c
@@ -0,0 +1,135 @@
+ /* zlib.c: compression module using zlib for heartbeat.
+ *
+ * Copyright (C) 2005 Guochun Shi <gshi at ncsa.uiuc.edu>
+ *
+ * SECURITY NOTE: It would be very easy for someone to masquerade as the
+ * device that you're pinging. If they don't know the password, all they can
+ * do is echo back the packets that you're sending out, or send out old ones.
+ * This does mean that if you're using such an approach, that someone could
+ * make you think you have quorum when you don't during a cluster partition.
+ * The danger in that seems small, but you never know ;-)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+
+
+#define PIL_PLUGINTYPE HB_COMPRESS_TYPE
+#define PIL_PLUGINTYPE_S HB_COMPRESS_TYPE_S
+#define PIL_PLUGIN zlib
+#define PIL_PLUGIN_S "zlib"
+#define PIL_PLUGINLICENSE LICENSE_LGPL
+#define PIL_PLUGINLICENSEURL URL_LGPL
+#include <lha_internal.h>
+#include <pils/plugin.h>
+#include <compress.h>
+#include <zlib.h>
+#include <clplumbing/cl_log.h>
+#include <string.h>
+
+
+static struct hb_compress_fns zlibOps;
+
+PIL_PLUGIN_BOILERPLATE2("1.0", Debug)
+
+static const PILPluginImports* PluginImports;
+static PILPlugin* OurPlugin;
+static PILInterface* OurInterface;
+static struct hb_media_imports* OurImports;
+static void* interfprivate;
+
+#define LOG PluginImports->log
+#define MALLOC PluginImports->alloc
+#define STRDUP PluginImports->mstrdup
+#define FREE PluginImports->mfree
+
+PIL_rc
+PIL_PLUGIN_INIT(PILPlugin*us, const PILPluginImports* imports);
+
+PIL_rc
+PIL_PLUGIN_INIT(PILPlugin*us, const PILPluginImports* imports)
+{
+ /* Force the compiler to do a little type checking */
+ (void)(PILPluginInitFun)PIL_PLUGIN_INIT;
+
+ PluginImports = imports;
+ OurPlugin = us;
+
+ /* Register ourself as a plugin */
+ imports->register_plugin(us, &OurPIExports);
+
+ /* Register our interface implementation */
+ return imports->register_interface(us, PIL_PLUGINTYPE_S
+ , PIL_PLUGIN_S
+ , &zlibOps
+ , NULL /*close */
+ , &OurInterface
+ , (void*)&OurImports
+ , interfprivate);
+}
+
+static int
+zlib_compress(char* dest, size_t* _destlen,
+ const char* src, size_t _srclen)
+{
+ int ret;
+ uLongf destlen = *_destlen;
+ uLongf srclen = _srclen;
+
+ ret = compress((Bytef *)dest, &destlen, (const Bytef *)src, srclen);
+ if (ret != Z_OK){
+ cl_log(LOG_ERR, "%s: compression failed",
+ __FUNCTION__);
+ return HA_FAIL;
+ }
+
+ *_destlen = destlen;
+ return HA_OK;
+
+}
+
+static int
+zlib_decompress(char* dest, size_t* _destlen,
+ const char* src, size_t _srclen)
+{
+
+ int ret;
+ uLongf destlen = *_destlen;
+ uLongf srclen = _srclen;
+
+ ret = uncompress((Bytef *)dest, &destlen, (const Bytef *)src, srclen);
+ if (ret != Z_OK){
+ cl_log(LOG_ERR, "%s: decompression failed",
+ __FUNCTION__);
+ return HA_FAIL;
+ }
+
+ *_destlen = destlen;
+
+ return HA_OK;
+}
+
+static const char*
+zlib_getname(void)
+{
+ return "zlib";
+}
+
+static struct hb_compress_fns zlibOps ={
+ zlib_compress,
+ zlib_decompress,
+ zlib_getname,
+};
diff --git a/lib/plugins/stonith/external/libvirt b/lib/plugins/stonith/external/libvirt
index 1fb09a3..23338b2 100644
--- a/lib/plugins/stonith/external/libvirt
+++ b/lib/plugins/stonith/external/libvirt
@@ -34,7 +34,9 @@ libvirt_start() {
return 0
fi
- if echo "$out" | grep -i 'Domain is already active' > /dev/null 2>&1
+ $VIRSH -c $hypervisor_uri dominfo $domain_id 2>&1 |
+ egrep -q '^State:.*(running|idle)|already active'
+ if [ $? -eq 0 ]
then
ha_log.sh notice "Domain $domain_id is already active"
return 0
@@ -58,7 +60,9 @@ libvirt_stop() {
return 0
fi
- if echo "$out" | grep -i 'domain is not running' > /dev/null 2>&1
+ $VIRSH -c $hypervisor_uri dominfo $domain_id 2>&1 |
+ egrep -q '^State:.*shut off|not found|not running'
+ if [ $? -eq 0 ]
then
ha_log.sh notice "Domain $domain_id is already stopped"
return 2
diff --git a/lib/plugins/stonith/external/vcenter b/lib/plugins/stonith/external/vcenter
index 9c7d962..8fc015e 100755
--- a/lib/plugins/stonith/external/vcenter
+++ b/lib/plugins/stonith/external/vcenter
@@ -25,7 +25,7 @@ sub dielog {
# Define command groups
my @configCommands = qw{getconfignames getinfo-devid getinfo-devname getinfo-devdescr getinfo-devurl getinfo-xml};
my @actionCommands = qw{reset on off};
-my @netCommands = (@actionCommands, qw{status gethosts});
+my @netCommands = (@actionCommands, qw{status gethosts listvms});
# Process command line arguments
my $command = $ARGV[0] || dielog("No command specified\n");
@@ -162,6 +162,9 @@ elsif ($command ~~ @netCommands) {
# VI API: searches the inventory tree for a VirtualMachine managed entity whose name matches
# the name of the virtual machine assigned to the target host in HOSTLIST
$vm = Vim::find_entity_view(view_type => "VirtualMachine", filter => { name => qr/\Q$host_to_vm{$targetHost}\E/i });
+ if (!defined $vm) {
+ dielog("Machine $targetHost was not found");
+ }
# VI API: retrieves the properties of the managed object reference runtime.host of the VirtualMachine
# managed entity obtained by the previous command
@@ -239,18 +242,23 @@ elsif ($command ~~ @netCommands) {
}
}
elsif ($command eq "gethosts") {
- # Create a regular expression to make vCenter find all the virtual machine matching
- # mirtual machine names specified in HOSTLIST
- # NOTE: this implementation make "gethosts" check that entries in HOSTLIST are consistent with VMware vCenter VM directory
- my $regex = join "|", map { qr/\Q$_\E/i } values %host_to_vm;
+ foreach my $key (keys(%host_to_vm)) {
+ print "$host_to_vm{$key} \n";
+ }
+ }
+ elsif ($command eq "listvms") {
eval {
- my $vms = Vim::find_entity_views(view_type => "VirtualMachine", filter => { name => qr/^($regex)$/ });
- foreach my $vm (@$vms) { print "$vm_to_host{(lc $vm->name)}\n" if exists $vm_to_host{(lc $vm->name)}; }
+ # VI API: Searches the inventory tree for all VirtualMachine managed objects
+ my $vms = Vim::find_entity_views(view_type => "VirtualMachine");
+ if (defined $vms) {
+ printf(STDERR "%-50s %-20s\n", "VM Name", "Power state");
+ print STDERR "-" x 70 . "\n";
+ foreach my $vm (@$vms) {
+ my $powerState = $vm->get_property('runtime.powerState')->val;
+ printf("%-50s %-20s\n", $vm->{name}, $powerState);
+ }
+ }
};
- if ($@) {
- if (ref($@) eq "SoapFault") { dielog("$@->detail\n"); }
- dielog($@);
- }
}
else { dielog("Invalid command specified: $command\n"); }
}
diff --git a/lib/plugins/stonith/rhcs.c b/lib/plugins/stonith/rhcs.c
index f499465..293a081 100644
--- a/lib/plugins/stonith/rhcs.c
+++ b/lib/plugins/stonith/rhcs.c
@@ -125,7 +125,7 @@ static const char * NOTpluginID = "RHCS device has been destroyed";
/* Run the command with op and return the exit status + the output
* (NULL -> discard output) */
static int rhcs_run_cmd(struct pluginDevice *sd, const char *op,
- char **output);
+ const char *host, char **output);
/* Just free up the configuration and the memory, if any */
static void rhcs_unconfig(struct pluginDevice *sd);
@@ -149,7 +149,7 @@ rhcs_status(StonithPlugin *s)
return(S_OOPS);
}
- rc = rhcs_run_cmd(sd, op, &output);
+ rc = rhcs_run_cmd(sd, op, NULL, &output);
if (rc != 0) {
LOG(PIL_CRIT, "%s: '%s %s' failed with rc %d",
__FUNCTION__, sd->subplugin, op, rc);
@@ -174,6 +174,8 @@ get_num_tokens(char *str)
{
int namecount = 0;
+ if (!str)
+ return namecount;
while (*str != EOS) {
str += strspn(str, WHITESPACE);
if (*str == EOS)
@@ -248,7 +250,6 @@ rhcs_reset_req(StonithPlugin * s, int request, const char * host)
const char * op;
int rc;
char * output = NULL;
- char *k, *v;
if (Debug) {
LOG(PIL_DEBUG, "%s: called.", __FUNCTION__);
@@ -286,13 +287,7 @@ rhcs_reset_req(StonithPlugin * s, int request, const char * host)
break;
}
- k = g_strdup("nodename");
- v = g_strdup(host);
- g_hash_table_insert(sd->cmd_opts, k, v);
- rc = rhcs_run_cmd(sd, op, &output);
- g_hash_table_remove(sd->cmd_opts, k);
- g_free(k);
- g_free(v);
+ rc = rhcs_run_cmd(sd, op, host, &output);
if (rc != 0) {
LOG(PIL_CRIT, "%s: '%s %s' for host %s failed with rc %d",
__FUNCTION__, sd->subplugin, op, host, rc);
@@ -329,6 +324,9 @@ rhcs_parse_config_info(struct pluginDevice* sd, StonithNVpair * info)
/* TODO: Maybe treat "" as delimeters too so
* whitespace can be passed to the plugins... */
for (nv = info; nv->s_name; nv++) {
+ if (!nv->s_name || !nv->s_value) {
+ continue;
+ }
key = STRDUP(nv->s_name);
if (!key) {
goto err_mem;
@@ -475,7 +473,7 @@ load_metadata(struct pluginDevice * sd)
LOG(PIL_DEBUG, "%s: called.", __FUNCTION__);
}
- rc = rhcs_run_cmd(sd, op, &ret);
+ rc = rhcs_run_cmd(sd, op, NULL, &ret);
if (rc != 0) {
LOG(PIL_CRIT, "%s: '%s %s' failed with rc %d",
__FUNCTION__, sd->subplugin, op, rc);
@@ -853,30 +851,35 @@ rhcs_new(const char *subplugin)
#define MAXLINE 512
static void
-rhcs_print_var(gpointer key, gpointer value, gpointer user_data)
+printparam_to_fd(int fd, const char *key, const char *value)
{
- int fd = GPOINTER_TO_UINT(user_data);
char arg[MAXLINE];
int cnt;
- cnt = snprintf(arg, MAXLINE, "%s=%s\n", (char *)key, (char *)value);
+ cnt = snprintf(arg, MAXLINE, "%s=%s\n", key, value);
if (cnt <= 0 || cnt >= MAXLINE) {
LOG(PIL_CRIT, "%s: param/value pair too large", __FUNCTION__);
return;
}
if (Debug) {
- LOG(PIL_DEBUG, "set rhcs plugin param '%s=%s'", (char *)key, (char *)value);
+ LOG(PIL_DEBUG, "set rhcs plugin param '%s=%s'", key, value);
}
if (write(fd, arg, cnt) < 0) {
LOG(PIL_CRIT, "%s: write: %m", __FUNCTION__);
}
}
+static void
+rhcs_print_var(gpointer key, gpointer value, gpointer user_data)
+{
+ printparam_to_fd(GPOINTER_TO_UINT(user_data), (char *)key, (char *)value);
+}
+
/* Run the command with op as command line argument(s) and return the exit
* status + the output */
static int
-rhcs_run_cmd(struct pluginDevice *sd, const char *op, char **output)
+rhcs_run_cmd(struct pluginDevice *sd, const char *op, const char *host, char **output)
{
const int BUFF_LEN=4096;
char buff[BUFF_LEN];
@@ -934,6 +937,10 @@ rhcs_run_cmd(struct pluginDevice *sd, const char *op, char **output)
close(fd2[1]);
if (sd->cmd_opts) {
+ printparam_to_fd(fd1[1], "agent", sd->subplugin);
+ printparam_to_fd(fd1[1], "action", op);
+ if( host )
+ printparam_to_fd(fd1[1], "nodename", host);
g_hash_table_foreach(sd->cmd_opts, rhcs_print_var,
GUINT_TO_POINTER(fd1[1]));
}
@@ -994,7 +1001,9 @@ rhcs_run_cmd(struct pluginDevice *sd, const char *op, char **output)
if (dup(fd2[1]) < 0)
goto err;
close(fd2[1]);
- if (execlp(cmd, cmd, "-o", op, NULL) < 0) {
+ rc = sd->cmd_opts ?
+ execlp(cmd, cmd, NULL) : execlp(cmd, cmd, "-o", op, NULL);
+ if (rc < 0) {
LOG(PIL_CRIT, "%s: Calling '%s' failed: %m",
__FUNCTION__, cmd);
}
diff --git a/lib/stonith/Makefile.am b/lib/stonith/Makefile.am
index a3ffbab..b91804f 100644
--- a/lib/stonith/Makefile.am
+++ b/lib/stonith/Makefile.am
@@ -43,7 +43,7 @@ meatclient_LDADD = $(GLIBLIB)
sbd_SOURCES = sbd-md.c sbd-common.c
sbd_CFLAGS = -D_GNU_SOURCE
-sbd_LDADD = $(GLIBLIB) \
+sbd_LDADD = $(GLIBLIB) -laio \
$(top_builddir)/lib/clplumbing/libplumb.la \
$(top_builddir)/lib/clplumbing/libplumbgpl.la
diff --git a/lib/stonith/ha_log.sh b/lib/stonith/ha_log.sh
index 26a2a27..c685d43 100755
--- a/lib/stonith/ha_log.sh
+++ b/lib/stonith/ha_log.sh
@@ -54,16 +54,24 @@ level_pres() {
esac
}
+set_logtag() {
+ # add parent pid to the logtag
+ if [ "$HA_LOGTAG" ]; then
+ if [ -n "$CRM_meta_st_device_id" ]; then
+ HA_LOGTAG="$HA_LOGTAG($CRM_meta_st_device_id)[$PPID]"
+ else
+ HA_LOGTAG="$HA_LOGTAG[$PPID]"
+ fi
+ fi
+}
+
ha_log() {
loglevel=$1
shift
prn_level=`level_pres $loglevel`
msg="$prn_level: $@"
- # add parent pid to the logtag
- if [ "$HA_LOGTAG" ]; then
- HA_LOGTAG="$HA_LOGTAG[$PPID]"
- fi
+ set_logtag
# if we're connected to a tty, then output to stderr
if tty >/dev/null; then
diff --git a/lib/stonith/sbd-common.c b/lib/stonith/sbd-common.c
index f9f16ac..74651b8 100644
--- a/lib/stonith/sbd-common.c
+++ b/lib/stonith/sbd-common.c
@@ -1,25 +1,3 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <asm/unistd.h>
-#include <ctype.h>
-#include <string.h>
-#include <syslog.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/ptrace.h>
-#include <fcntl.h>
-#include <time.h>
-#include <clplumbing/cl_log.h>
-#include <clplumbing/coredumps.h>
-#include <clplumbing/realtime.h>
-#include <clplumbing/cl_reboot.h>
-#include <malloc.h>
-#include <sys/utsname.h>
-#include <sys/ioctl.h>
-#include <linux/types.h>
-#include <linux/watchdog.h>
-#include <linux/fs.h>
#include "sbd.h"
@@ -33,11 +11,13 @@ unsigned long timeout_watchdog_warn = 3;
int timeout_allocate = 2;
int timeout_loop = 1;
int timeout_msgwait = 10;
+int timeout_io = 3;
int watchdog_use = 0;
int watchdog_set_timeout = 1;
int skip_rt = 0;
int debug = 0;
+int debug_mode = 0;
const char *watchdogdev = "/dev/watchdog";
char * local_uname;
@@ -72,8 +52,12 @@ usage(void)
"-4 <N> Set msgwait timeout to N seconds (optional, create only)\n"
"-5 <N> Warn if loop latency exceeds threshold (optional, watch only)\n"
" (default is 3, set to 0 to disable)\n"
-"-t <N> Interval in seconds for automatic child restarts (optional)\n"
-" (default is 3600, set to 0 to disable)\n"
+"-I <N> Async IO read timeout (defaults to 3 * loop timeout, optional)\n"
+"-t <N> Dampening delay before faulty servants are restarted (optional)\n"
+" (default is 60, set to 0 to disable)\n"
+"-F <N> # of failures before a servant is considered faulty (optional)\n"
+" (default is 10, set to 0 to disable)\n"
+"-Z Enable trace mode. WARNING: UNSAFE FOR PRODUCTION!\n"
"Commands:\n"
"create initialize N slots on <dev> - OVERWRITES DEVICE!\n"
"list List all allocated slots on device, and messages.\n"
@@ -212,27 +196,49 @@ maximize_priority(void)
}
}
-int
+void
+close_device(struct sbd_context *st)
+{
+ close(st->devfd);
+ free(st);
+}
+
+struct sbd_context *
open_device(const char* devname)
{
- int devfd;
+ struct sbd_context *st;
+
if (!devname)
- return -1;
+ return NULL;
- devfd = open(devname, O_SYNC|O_RDWR|O_DIRECT);
+ st = malloc(sizeof(struct sbd_context));
+ if (!st)
+ return NULL;
+ memset(st, 0, sizeof(struct sbd_context));
- if (devfd == -1) {
+ if (io_setup(1, &st->ioctx) != 0) {
+ cl_perror("io_setup failed");
+ free(st);
+ return NULL;
+ }
+
+ st->devfd = open(devname, O_SYNC|O_RDWR|O_DIRECT);
+
+ if (st->devfd == -1) {
cl_perror("Opening device %s failed.", devname);
- return -1;
+ free(st);
+ return NULL;
}
- ioctl(devfd, BLKSSZGET, §or_size);
+ ioctl(st->devfd, BLKSSZGET, §or_size);
if (sector_size == 0) {
cl_perror("Get sector size failed.\n");
- return -1;
+ close_device(st);
+ return NULL;
}
- return devfd;
+
+ return st;
}
signed char
@@ -297,14 +303,14 @@ char2cmd(const char cmd)
}
int
-sector_write(int devfd, int sector, const void *data)
+sector_write(struct sbd_context *st, int sector, const void *data)
{
- if (lseek(devfd, sector_size*sector, 0) < 0) {
+ if (lseek(st->devfd, sector_size*sector, 0) < 0) {
cl_perror("sector_write: lseek() failed");
return -1;
}
- if (write(devfd, data, sector_size) <= 0) {
+ if (write(st->devfd, data, sector_size) <= 0) {
cl_perror("sector_write: write_sector() failed");
return -1;
}
@@ -312,55 +318,83 @@ sector_write(int devfd, int sector, const void *data)
}
int
-sector_read(int devfd, int sector, void *data)
+sector_read(struct sbd_context *st, int sector, void *data)
{
- if (lseek(devfd, sector_size*sector, 0) < 0) {
- cl_perror("sector_read: lseek() failed");
+ struct timespec timeout;
+ struct io_event event;
+ struct iocb *ios[1] = { &st->io };
+ long r;
+
+ timeout.tv_sec = timeout_io;
+ timeout.tv_nsec = 0;
+
+ memset(&st->io, 0, sizeof(struct iocb));
+ io_prep_pread(&st->io, st->devfd, data, sector_size, sector_size * sector);
+ if (io_submit(st->ioctx, 1, ios) != 1) {
+ cl_log(LOG_ERR, "Failed to submit IO request!");
return -1;
}
- if (read(devfd, data, sector_size) < sector_size) {
- cl_perror("sector_read: read() failed");
+ errno = 0;
+ r = io_getevents(st->ioctx, 1L, 1L, &event, &timeout);
+
+ if (r < 0 ) {
+ cl_log(LOG_ERR, "Failed to retrieve IO events");
+ return -1;
+ } else if (r < 1L) {
+ cl_log(LOG_WARNING, "Cancelling IO request due to timeout");
+ r = io_cancel(st->ioctx, ios[0], &event);
+ if (r) {
+ cl_log(LOG_ERR, "Could not cancel IO request!");
+ /* TODO: Couldn't cancel the IO */
+ }
+ return -1;
+ }
+
+ /* IO is happy */
+ if (event.res == sector_size) {
+ return 0;
+ } else {
+ cl_log(LOG_ERR, "Short read");
return -1;
}
- return(0);
}
int
-slot_read(int devfd, int slot, struct sector_node_s *s_node)
+slot_read(struct sbd_context *st, int slot, struct sector_node_s *s_node)
{
- return sector_read(devfd, SLOT_TO_SECTOR(slot), s_node);
+ return sector_read(st, SLOT_TO_SECTOR(slot), s_node);
}
int
-slot_write(int devfd, int slot, const struct sector_node_s *s_node)
+slot_write(struct sbd_context *st, int slot, const struct sector_node_s *s_node)
{
- return sector_write(devfd, SLOT_TO_SECTOR(slot), s_node);
+ return sector_write(st, SLOT_TO_SECTOR(slot), s_node);
}
int
-mbox_write(int devfd, int mbox, const struct sector_mbox_s *s_mbox)
+mbox_write(struct sbd_context *st, int mbox, const struct sector_mbox_s *s_mbox)
{
- return sector_write(devfd, MBOX_TO_SECTOR(mbox), s_mbox);
+ return sector_write(st, MBOX_TO_SECTOR(mbox), s_mbox);
}
int
-mbox_read(int devfd, int mbox, struct sector_mbox_s *s_mbox)
+mbox_read(struct sbd_context *st, int mbox, struct sector_mbox_s *s_mbox)
{
- return sector_read(devfd, MBOX_TO_SECTOR(mbox), s_mbox);
+ return sector_read(st, MBOX_TO_SECTOR(mbox), s_mbox);
}
int
-mbox_write_verify(int devfd, int mbox, const struct sector_mbox_s *s_mbox)
+mbox_write_verify(struct sbd_context *st, int mbox, const struct sector_mbox_s *s_mbox)
{
void *data;
int rc = 0;
- if (sector_write(devfd, MBOX_TO_SECTOR(mbox), s_mbox) < 0)
+ if (sector_write(st, MBOX_TO_SECTOR(mbox), s_mbox) < 0)
return -1;
data = sector_alloc();
- if (sector_read(devfd, MBOX_TO_SECTOR(mbox), data) < 0) {
+ if (sector_read(st, MBOX_TO_SECTOR(mbox), data) < 0) {
rc = -1;
goto out;
}
@@ -377,20 +411,20 @@ out:
return rc;
}
-int header_write(int devfd, struct sector_header_s *s_header)
+int header_write(struct sbd_context *st, struct sector_header_s *s_header)
{
s_header->sector_size = htonl(s_header->sector_size);
s_header->timeout_watchdog = htonl(s_header->timeout_watchdog);
s_header->timeout_allocate = htonl(s_header->timeout_allocate);
s_header->timeout_loop = htonl(s_header->timeout_loop);
s_header->timeout_msgwait = htonl(s_header->timeout_msgwait);
- return sector_write(devfd, 0, s_header);
+ return sector_write(st, 0, s_header);
}
int
-header_read(int devfd, struct sector_header_s *s_header)
+header_read(struct sbd_context *st, struct sector_header_s *s_header)
{
- if (sector_read(devfd, 0, s_header) < 0)
+ if (sector_read(st, 0, s_header) < 0)
return -1;
s_header->sector_size = ntohl(s_header->sector_size);
@@ -426,18 +460,18 @@ valid_header(const struct sector_header_s *s_header)
}
struct sector_header_s *
-header_get(int devfd)
+header_get(struct sbd_context *st)
{
struct sector_header_s *s_header;
s_header = sector_alloc();
- if (header_read(devfd, s_header) < 0) {
- cl_log(LOG_ERR, "Unable to read header from device %d", devfd);
+ if (header_read(st, s_header) < 0) {
+ cl_log(LOG_ERR, "Unable to read header from device %d", st->devfd);
return NULL;
}
if (valid_header(s_header) < 0) {
- cl_log(LOG_ERR, "header on device %d is not valid.", devfd);
+ cl_log(LOG_ERR, "header on device %d is not valid.", st->devfd);
return NULL;
}
@@ -448,7 +482,7 @@ header_get(int devfd)
}
int
-init_device(int devfd)
+init_device(struct sbd_context *st)
{
struct sector_header_s *s_header;
struct sector_node_s *s_node;
@@ -469,30 +503,30 @@ init_device(int devfd)
s_header->timeout_loop = timeout_loop;
s_header->timeout_msgwait = timeout_msgwait;
- fstat(devfd, &s);
+ fstat(st->devfd, &s);
/* printf("st_size = %ld, st_blksize = %ld, st_blocks = %ld\n",
s.st_size, s.st_blksize, s.st_blocks); */
cl_log(LOG_INFO, "Creating version %d header on device %d",
s_header->version,
- devfd);
+ st->devfd);
fprintf(stdout, "Creating version %d header on device %d\n",
s_header->version,
- devfd);
- if (header_write(devfd, s_header) < 0) {
+ st->devfd);
+ if (header_write(st, s_header) < 0) {
rc = -1; goto out;
}
cl_log(LOG_INFO, "Initializing %d slots on device %d",
s_header->slots,
- devfd);
+ st->devfd);
fprintf(stdout, "Initializing %d slots on device %d\n",
s_header->slots,
- devfd);
+ st->devfd);
for (i=0;i < s_header->slots;i++) {
- if (slot_write(devfd, i, s_node) < 0) {
+ if (slot_write(st, i, s_node) < 0) {
rc = -1; goto out;
}
- if (mbox_write(devfd, i, s_mbox) < 0) {
+ if (mbox_write(st, i, s_mbox) < 0) {
rc = -1; goto out;
}
}
@@ -507,7 +541,7 @@ out: free(s_node);
* slot number. If not found, returns -1.
* This is necessary because slots might not be continuous. */
int
-slot_lookup(int devfd, const struct sector_header_s *s_header, const char *name)
+slot_lookup(struct sbd_context *st, const struct sector_header_s *s_header, const char *name)
{
struct sector_node_s *s_node = NULL;
int i;
@@ -521,8 +555,8 @@ slot_lookup(int devfd, const struct sector_header_s *s_header, const char *name)
s_node = sector_alloc();
for (i=0; i < s_header->slots; i++) {
- if (slot_read(devfd, i, s_node) < 0) {
- rc = -1; goto out;
+ if (slot_read(st, i, s_node) < 0) {
+ rc = -2; goto out;
}
if (s_node->in_use != 0) {
if (strncasecmp(s_node->name, name,
@@ -538,7 +572,7 @@ out: free(s_node);
}
int
-slot_unused(int devfd, const struct sector_header_s *s_header)
+slot_unused(struct sbd_context *st, const struct sector_header_s *s_header)
{
struct sector_node_s *s_node;
int i;
@@ -547,7 +581,7 @@ slot_unused(int devfd, const struct sector_header_s *s_header)
s_node = sector_alloc();
for (i=0; i < s_header->slots; i++) {
- if (slot_read(devfd, i, s_node) < 0) {
+ if (slot_read(st, i, s_node) < 0) {
rc = -1; goto out;
}
if (s_node->in_use == 0) {
@@ -561,7 +595,7 @@ out: free(s_node);
int
-slot_allocate(int devfd, const char *name)
+slot_allocate(struct sbd_context *st, const char *name)
{
struct sector_header_s *s_header = NULL;
struct sector_node_s *s_node = NULL;
@@ -575,7 +609,7 @@ slot_allocate(int devfd, const char *name)
rc = -1; goto out;
}
- s_header = header_get(devfd);
+ s_header = header_get(st);
if (!s_header) {
rc = -1; goto out;
}
@@ -584,19 +618,24 @@ slot_allocate(int devfd, const char *name)
s_mbox = sector_alloc();
while (1) {
- i = slot_lookup(devfd, s_header, name);
- if (i >= 0) {
+ i = slot_lookup(st, s_header, name);
+ if ((i >= 0) || (i == -2)) {
+ /* -1 is "no slot found", in which case we
+ * proceed to allocate a new one.
+ * -2 is "read error during lookup", in which
+ * case we error out too
+ * >= 0 is "slot already allocated" */
rc = i; goto out;
}
- i = slot_unused(devfd, s_header);
+ i = slot_unused(st, s_header);
if (i >= 0) {
cl_log(LOG_INFO, "slot %d is unused - trying to own", i);
fprintf(stdout, "slot %d is unused - trying to own\n", i);
memset(s_node, 0, sizeof(*s_node));
s_node->in_use = 1;
strncpy(s_node->name, name, sizeof(s_node->name));
- if (slot_write(devfd, i, s_node) < 0) {
+ if (slot_write(st, i, s_node) < 0) {
rc = -1; goto out;
}
sleep(timeout_allocate);
@@ -614,7 +653,7 @@ out: free(s_node);
}
int
-slot_list(int devfd)
+slot_list(struct sbd_context *st)
{
struct sector_header_s *s_header = NULL;
struct sector_node_s *s_node = NULL;
@@ -622,7 +661,7 @@ slot_list(int devfd)
int i;
int rc = 0;
- s_header = header_get(devfd);
+ s_header = header_get(st);
if (!s_header) {
rc = -1; goto out;
}
@@ -631,11 +670,11 @@ slot_list(int devfd)
s_mbox = sector_alloc();
for (i=0; i < s_header->slots; i++) {
- if (slot_read(devfd, i, s_node) < 0) {
+ if (slot_read(st, i, s_node) < 0) {
rc = -1; goto out;
}
if (s_node->in_use > 0) {
- if (mbox_read(devfd, i, s_mbox) < 0) {
+ if (mbox_read(st, i, s_mbox) < 0) {
rc = -1; goto out;
}
printf("%d\t%s\t%s\t%s\n",
@@ -651,7 +690,7 @@ out: free(s_node);
}
int
-slot_msg(int devfd, const char *name, const char *cmd)
+slot_msg(struct sbd_context *st, const char *name, const char *cmd)
{
struct sector_header_s *s_header = NULL;
struct sector_mbox_s *s_mbox = NULL;
@@ -663,7 +702,7 @@ slot_msg(int devfd, const char *name, const char *cmd)
rc = -1; goto out;
}
- s_header = header_get(devfd);
+ s_header = header_get(st);
if (!s_header) {
rc = -1; goto out;
}
@@ -672,7 +711,7 @@ slot_msg(int devfd, const char *name, const char *cmd)
name = local_uname;
}
- mbox = slot_lookup(devfd, s_header, name);
+ mbox = slot_lookup(st, s_header, name);
if (mbox < 0) {
cl_log(LOG_ERR, "slot_msg(): No slot found for %s.", name);
rc = -1; goto out;
@@ -690,7 +729,7 @@ slot_msg(int devfd, const char *name, const char *cmd)
cl_log(LOG_INFO, "Writing %s to node slot %s",
cmd, name);
- if (mbox_write_verify(devfd, mbox, s_mbox) < -1) {
+ if (mbox_write_verify(st, mbox, s_mbox) < -1) {
rc = -1; goto out;
}
if (strcasecmp(cmd, "exit") != 0) {
@@ -705,7 +744,7 @@ out: free(s_mbox);
}
int
-slot_ping(int devfd, const char *name)
+slot_ping(struct sbd_context *st, const char *name)
{
struct sector_header_s *s_header = NULL;
struct sector_mbox_s *s_mbox = NULL;
@@ -718,7 +757,7 @@ slot_ping(int devfd, const char *name)
rc = -1; goto out;
}
- s_header = header_get(devfd);
+ s_header = header_get(st);
if (!s_header) {
rc = -1; goto out;
}
@@ -727,7 +766,7 @@ slot_ping(int devfd, const char *name)
name = local_uname;
}
- mbox = slot_lookup(devfd, s_header, name);
+ mbox = slot_lookup(st, s_header, name);
if (mbox < 0) {
cl_log(LOG_ERR, "slot_msg(): No slot found for %s.", name);
rc = -1; goto out;
@@ -739,13 +778,13 @@ slot_ping(int devfd, const char *name)
strncpy(s_mbox->from, local_uname, sizeof(s_mbox->from)-1);
cl_log(LOG_DEBUG, "Pinging node %s", name);
- if (mbox_write(devfd, mbox, s_mbox) < -1) {
+ if (mbox_write(st, mbox, s_mbox) < -1) {
rc = -1; goto out;
}
rc = -1;
while (waited <= timeout_msgwait) {
- if (mbox_read(devfd, mbox, s_mbox) < 0)
+ if (mbox_read(st, mbox, s_mbox) < 0)
break;
if (s_mbox->cmd != SBD_MSG_TEST) {
rc = 0;
@@ -821,6 +860,17 @@ do_crashdump(void)
void
do_reset(void)
{
+ if (debug_mode == 2) {
+ cl_log(LOG_ERR, "Skipping request to suicide due to DEBUG MODE!");
+ watchdog_close();
+ exit(0);
+ }
+ if (debug_mode == 1) {
+ cl_log(LOG_ERR, "Request to suicide changed to kdump due to DEBUG MODE!");
+ watchdog_close();
+ sysrq_trigger('c');
+ exit(0);
+ }
sysrq_trigger('b');
cl_reboot(5, "sbd is self-fencing (reset)");
sleep(timeout_watchdog * 2);
@@ -830,6 +880,17 @@ do_reset(void)
void
do_off(void)
{
+ if (debug_mode == 2) {
+ cl_log(LOG_ERR, "Skipping request to power-off due to DEBUG MODE!");
+ watchdog_close();
+ exit(0);
+ }
+ if (debug_mode == 1) {
+ cl_log(LOG_ERR, "Request to power-off changed to kdump due to DEBUG MODE!");
+ watchdog_close();
+ sysrq_trigger('c');
+ exit(0);
+ }
sysrq_trigger('o');
cl_reboot(5, "sbd is self-fencing (power-off)");
sleep(timeout_watchdog * 2);
@@ -869,10 +930,10 @@ make_daemon(void)
}
int
-header_dump(int devfd)
+header_dump(struct sbd_context *st)
{
struct sector_header_s *s_header;
- s_header = header_get(devfd);
+ s_header = header_get(st);
if (s_header == NULL)
return -1;
diff --git a/lib/stonith/sbd-md.c b/lib/stonith/sbd-md.c
index 7e856e6..4fbfb5d 100644
--- a/lib/stonith/sbd-md.c
+++ b/lib/stonith/sbd-md.c
@@ -16,47 +16,21 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include <signal.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <asm/unistd.h>
-#include <ctype.h>
-#include <string.h>
-#include <syslog.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/ptrace.h>
-#include <fcntl.h>
-#include <time.h>
-#include <clplumbing/cl_log.h>
-#include <clplumbing/coredumps.h>
-#include <clplumbing/realtime.h>
-#include <clplumbing/cl_reboot.h>
-#include <clplumbing/setproctitle.h>
-#include <malloc.h>
-#include <time.h>
-#include <sys/utsname.h>
-#include <sys/ioctl.h>
-#include <linux/types.h>
-#include <linux/watchdog.h>
-#include <linux/fs.h>
-
#include "sbd.h"
struct servants_list_item *servants_leader = NULL;
static int servant_count = 0;
-static int servant_restart_interval = 3600;
+static int servant_restart_interval = 60;
+static int servant_restart_count = 10;
+static int servant_inform_parent = 0;
/* signals reserved for multi-disk sbd */
#define SIG_LIVENESS (SIGRTMIN + 1) /* report liveness of the disk */
#define SIG_EXITREQ (SIGRTMIN + 2) /* exit request to inquisitor */
#define SIG_TEST (SIGRTMIN + 3) /* trigger self test */
#define SIG_RESTART (SIGRTMIN + 4) /* trigger restart of all failed disk */
+#define SIG_IO_FAIL (SIGRTMIN + 5) /* the IO child requests to be considered failed */
/* FIXME: should add dynamic check of SIG_XX >= SIGRTMAX */
/* Debug Helper */
@@ -104,18 +78,18 @@ int assign_servant(const char* devname, functionp_t functionp, const void* argp)
int init_devices()
{
int rc = 0;
- int devfd;
+ struct sbd_context *st;
struct servants_list_item *s;
for (s = servants_leader; s; s = s->next) {
fprintf(stdout, "Initializing device %s\n",
s->devname);
- devfd = open_device(s->devname);
- if (devfd == -1) {
+ st = open_device(s->devname);
+ if (!st) {
return -1;
}
- rc = init_device(devfd);
- close(devfd);
+ rc = init_device(st);
+ close_device(st);
if (rc == -1) {
fprintf(stderr, "Failed to init device %s\n", s->devname);
return rc;
@@ -128,14 +102,14 @@ int init_devices()
int slot_msg_wrapper(const char* devname, const void* argp)
{
int rc = 0;
- int devfd;
+ struct sbd_context *st;
const struct slot_msg_arg_t* arg = (const struct slot_msg_arg_t*)argp;
- devfd = open_device(devname);
- if (devfd == -1)
+ st = open_device(devname);
+ if (!st)
return -1;
- rc = slot_msg(devfd, arg->name, arg->msg);
- close(devfd);
+ rc = slot_msg(st, arg->name, arg->msg);
+ close_device(st);
return rc;
}
@@ -143,33 +117,33 @@ int slot_ping_wrapper(const char* devname, const void* argp)
{
int rc = 0;
const char* name = (const char*)argp;
- int devfd;
+ struct sbd_context *st;
- devfd = open_device(devname);
- if (devfd == -1)
+ st = open_device(devname);
+ if (!st)
return -1;
- rc = slot_ping(devfd, name);
- close(devfd);
+ rc = slot_ping(st, name);
+ close_device(st);
return rc;
}
int allocate_slots(const char *name)
{
int rc = 0;
- int devfd;
+ struct sbd_context *st;
struct servants_list_item *s;
for (s = servants_leader; s; s = s->next) {
fprintf(stdout, "Trying to allocate slot for %s on device %s.\n",
name,
s->devname);
- devfd = open_device(s->devname);
- if (devfd == -1) {
+ st = open_device(s->devname);
+ if (!st) {
return -1;
}
- rc = slot_allocate(devfd, name);
- close(devfd);
- if (rc == -1)
+ rc = slot_allocate(st, name);
+ close_device(st);
+ if (rc < 0)
return rc;
fprintf(stdout, "Slot for %s has been allocated on %s.\n",
name,
@@ -182,15 +156,15 @@ int list_slots()
{
int rc = 0;
struct servants_list_item *s;
- int devfd;
+ struct sbd_context *st;
for (s = servants_leader; s; s = s->next) {
DBGPRINT("list slots on device %s\n", s->devname);
- devfd = open_device(s->devname);
- if (devfd == -1)
+ st = open_device(s->devname);
+ if (!st)
return -1;
- rc = slot_list(devfd);
- close(devfd);
+ rc = slot_list(st);
+ close_device(st);
if (rc == -1)
return rc;
}
@@ -207,7 +181,6 @@ int ping_via_slots(const char *name)
siginfo_t sinfo;
struct servants_list_item *s;
- DBGPRINT("you shall know no fear\n");
sigemptyset(&procmask);
sigaddset(&procmask, SIGCHLD);
sigprocmask(SIG_BLOCK, &procmask, NULL);
@@ -245,6 +218,20 @@ int ping_via_slots(const char *name)
return 0;
}
+/* This is a bit hackish, but the easiest way to rewire all process
+ * exits to send the desired signal to the parent. */
+void servant_exit(void)
+{
+ pid_t ppid;
+ union sigval signal_value;
+
+ ppid = getppid();
+ if (servant_inform_parent) {
+ memset(&signal_value, 0, sizeof(signal_value));
+ sigqueue(ppid, SIG_IO_FAIL, signal_value);
+ }
+}
+
int servant(const char *diskname, const void* argp)
{
struct sector_mbox_s *s_mbox = NULL;
@@ -253,7 +240,7 @@ int servant(const char *diskname, const void* argp)
time_t t0, t1, latency;
union sigval signal_value;
sigset_t servant_masks;
- int devfd;
+ struct sbd_context *st;
pid_t ppid;
if (!diskname) {
@@ -261,6 +248,8 @@ int servant(const char *diskname, const void* argp)
return -1;
}
+ cl_log(LOG_INFO, "Servant starting for device %s", diskname);
+
/* Block most of the signals */
sigfillset(&servant_masks);
sigdelset(&servant_masks, SIGKILL);
@@ -272,12 +261,15 @@ int servant(const char *diskname, const void* argp)
/* FIXME: check error */
sigprocmask(SIG_SETMASK, &servant_masks, NULL);
- devfd = open_device(diskname);
- if (devfd == -1) {
+ atexit(servant_exit);
+ servant_inform_parent = 1;
+
+ st = open_device(diskname);
+ if (!st) {
return -1;
}
- mbox = slot_allocate(devfd, local_uname);
+ mbox = slot_allocate(st, local_uname);
if (mbox < 0) {
cl_log(LOG_ERR,
"No slot allocated, and automatic allocation failed for disk %s.",
@@ -289,7 +281,7 @@ int servant(const char *diskname, const void* argp)
set_proc_title("sbd: watcher: %s - slot: %d", diskname, mbox);
s_mbox = sector_alloc();
- if (mbox_write(devfd, mbox, s_mbox) < 0) {
+ if (mbox_write(st, mbox, s_mbox) < 0) {
rc = -1;
goto out;
}
@@ -308,7 +300,7 @@ int servant(const char *diskname, const void* argp)
do_reset();
}
- if (mbox_read(devfd, mbox, s_mbox) < 0) {
+ if (mbox_read(st, mbox, s_mbox) < 0) {
cl_log(LOG_ERR, "mbox read failed in servant.");
exit(1);
}
@@ -321,7 +313,7 @@ int servant(const char *diskname, const void* argp)
switch (s_mbox->cmd) {
case SBD_MSG_TEST:
memset(s_mbox, 0, sizeof(*s_mbox));
- mbox_write(devfd, mbox, s_mbox);
+ mbox_write(st, mbox, s_mbox);
sigqueue(ppid, SIG_TEST, signal_value);
break;
case SBD_MSG_RESET:
@@ -345,7 +337,7 @@ int servant(const char *diskname, const void* argp)
cl_log(LOG_ERR, "Unknown message on disk %s",
diskname);
memset(s_mbox, 0, sizeof(*s_mbox));
- mbox_write(devfd, mbox, s_mbox);
+ mbox_write(st, mbox, s_mbox);
break;
}
}
@@ -365,8 +357,10 @@ int servant(const char *diskname, const void* argp)
}
out:
free(s_mbox);
- close(devfd);
- devfd = -1;
+ close_device(st);
+ if (rc == 0) {
+ servant_inform_parent = 0;
+ }
return rc;
}
@@ -435,20 +429,31 @@ int check_all_dead(void)
}
-void servants_start(void)
+void servant_start(struct servants_list_item *s)
{
- struct servants_list_item *s;
int r = 0;
union sigval svalue;
+ if (s->pid != 0) {
+ r = sigqueue(s->pid, 0, svalue);
+ if ((r != -1 || errno != ESRCH))
+ return;
+ }
+ cl_log(LOG_INFO, "Starting servant for device %s",
+ s->devname);
+ s->restarts++;
+ s->pid = assign_servant(s->devname, servant, NULL);
+ clock_gettime(CLOCK_MONOTONIC, &s->t_started);
+ return;
+}
+
+void servants_start(void)
+{
+ struct servants_list_item *s;
+
for (s = servants_leader; s; s = s->next) {
- if (s->pid != 0) {
- r = sigqueue(s->pid, 0, svalue);
- if ((r != -1 || errno != ESRCH))
- continue;
- }
s->restarts = 0;
- s->pid = assign_servant(s->devname, servant, NULL);
+ servant_start(s);
}
}
@@ -465,17 +470,17 @@ void servants_kill(void)
int check_timeout_inconsistent(void)
{
- int devfd;
+ struct sbd_context *st;
struct sector_header_s *hdr_cur = 0, *hdr_last = 0;
struct servants_list_item* s;
int inconsistent = 0;
for (s = servants_leader; s; s = s->next) {
- devfd = open_device(s->devname);
- if (devfd < 0)
+ st = open_device(s->devname);
+ if (!st)
continue;
- hdr_cur = header_get(devfd);
- close(devfd);
+ hdr_cur = header_get(st);
+ close_device(st);
if (!hdr_cur)
continue;
if (hdr_last) {
@@ -509,33 +514,14 @@ inline void cleanup_servant_by_pid(pid_t pid)
s = lookup_servant_by_pid(pid);
if (s) {
+ cl_log(LOG_WARNING, "Servant for %s (pid: %i) has terminated",
+ s->devname, s->pid);
s->pid = 0;
} else {
- /* TODO: This points to an inconsistency in our internal
- * data - how to recover? */
- cl_log(LOG_ERR, "Cannot cleanup after unknown pid %i",
- pid);
- }
-}
-
-void restart_servant_by_pid(pid_t pid)
-{
- struct servants_list_item* s;
-
- s = lookup_servant_by_pid(pid);
- if (s) {
- if (s->restarts < 10) {
- s->pid = assign_servant(s->devname, servant, NULL);
- s->restarts++;
- } else {
- cl_log(LOG_WARNING, "Max retry count reached: not restarting servant for %s",
- s->devname);
- }
-
- } else {
- /* TODO: This points to an inconsistency in our internal
- * data - how to recover? */
- cl_log(LOG_ERR, "Cannot restart unknown pid %i",
+ /* This most likely is a stray signal from somewhere, or
+ * a SIGCHLD for a process that has previously
+ * explicitly disconnected. */
+ cl_log(LOG_INFO, "cleanup_servant: Nothing known about pid %i",
pid);
}
}
@@ -561,32 +547,30 @@ int inquisitor_decouple(void)
void inquisitor_child(void)
{
- int sig, pid, i;
+ int sig, pid;
sigset_t procmask;
siginfo_t sinfo;
- int *reports;
int status;
struct timespec timeout;
int good_servants = 0;
int exiting = 0;
int decoupled = 0;
time_t latency;
- struct timespec t_last_tickle, t_now, t_last_restarted;
-
- set_proc_title("sbd: inquisitor");
+ struct timespec t_last_tickle, t_now;
+ struct servants_list_item* s;
- reports = malloc(sizeof(int) * servant_count);
- if (!reports) {
- cl_log(LOG_ERR, "malloc failed");
- exit(1);
+ if (debug_mode) {
+ cl_log(LOG_ERR, "DEBUG MODE IS ACTIVE - DO NOT RUN IN PRODUCTION!");
}
- memset(reports, 0, sizeof(int) * servant_count);
+
+ set_proc_title("sbd: inquisitor");
sigemptyset(&procmask);
sigaddset(&procmask, SIGCHLD);
sigaddset(&procmask, SIG_LIVENESS);
sigaddset(&procmask, SIG_EXITREQ);
sigaddset(&procmask, SIG_TEST);
+ sigaddset(&procmask, SIG_IO_FAIL);
sigaddset(&procmask, SIGUSR1);
sigaddset(&procmask, SIGUSR2);
sigprocmask(SIG_BLOCK, &procmask, NULL);
@@ -597,12 +581,13 @@ void inquisitor_child(void)
timeout.tv_nsec = 0;
good_servants = 0;
clock_gettime(CLOCK_MONOTONIC, &t_last_tickle);
- clock_gettime(CLOCK_MONOTONIC, &t_last_restarted);
while (1) {
sig = sigtimedwait(&procmask, &sinfo, &timeout);
DBGPRINT("got signal %d\n", sig);
+ clock_gettime(CLOCK_MONOTONIC, &t_now);
+
if (sig == SIG_EXITREQ) {
servants_kill();
watchdog_close();
@@ -611,27 +596,26 @@ void inquisitor_child(void)
while ((pid = waitpid(-1, &status, WNOHANG))) {
if (pid == -1 && errno == ECHILD) {
break;
- } else if (exiting) {
- cleanup_servant_by_pid(pid);
} else {
- restart_servant_by_pid(pid);
+ cleanup_servant_by_pid(pid);
}
}
+ } else if (sig == SIG_IO_FAIL) {
+ s = lookup_servant_by_pid(sinfo.si_pid);
+ if (s) {
+ cl_log(LOG_WARNING, "Servant for %s requests to be disowned",
+ s->devname);
+ cleanup_servant_by_pid(sinfo.si_pid);
+ }
} else if (sig == SIG_LIVENESS) {
- for (i = 0; i < servant_count; i++) {
- if (reports[i] == sinfo.si_pid) {
- break;
- } else if (reports[i] == 0) {
- reports[i] = sinfo.si_pid;
- good_servants++;
- break;
- }
+ s = lookup_servant_by_pid(sinfo.si_pid);
+ if (s) {
+ clock_gettime(CLOCK_MONOTONIC, &s->t_last);
}
} else if (sig == SIG_TEST) {
} else if (sig == SIGUSR1) {
if (exiting)
continue;
- clock_gettime(CLOCK_MONOTONIC, &t_last_restarted);
servants_start();
}
@@ -642,8 +626,23 @@ void inquisitor_child(void)
continue;
}
+ good_servants = 0;
+ for (s = servants_leader; s; s = s->next) {
+ int age = t_now.tv_sec - s->t_last.tv_sec;
+
+ if (!s->t_last.tv_sec)
+ continue;
+
+ if (age < timeout_watchdog) {
+ good_servants++;
+ } else {
+ if (!s->restart_blocked)
+ cl_log(LOG_WARNING, "Servant for %s outdated (age: %d)",
+ s->devname, age);
+ }
+ }
+
if (quorum_read(good_servants)) {
- DBGPRINT("Enough liveness messages\n");
if (!decoupled) {
if (inquisitor_decouple() < 0) {
servants_kill();
@@ -656,11 +655,8 @@ void inquisitor_child(void)
watchdog_tickle();
clock_gettime(CLOCK_MONOTONIC, &t_last_tickle);
- memset(reports, 0, sizeof(int) * servant_count);
- good_servants = 0;
}
- clock_gettime(CLOCK_MONOTONIC, &t_now);
latency = t_now.tv_sec - t_last_tickle.tv_sec;
if (timeout_watchdog && (latency > timeout_watchdog)) {
if (!decoupled) {
@@ -671,7 +667,14 @@ void inquisitor_child(void)
exiting = 1;
continue;
}
- do_reset();
+ if (debug_mode < 2) {
+ /* At level 2, we do nothing, but expect
+ * things to eventually return to
+ * normal. */
+ do_reset();
+ } else {
+ cl_log(LOG_ERR, "SBD: DEBUG MODE: Would have fenced due to timeout!");
+ }
}
if (timeout_watchdog_warn && (latency > timeout_watchdog_warn)) {
cl_log(LOG_WARNING,
@@ -679,12 +682,27 @@ void inquisitor_child(void)
(int)latency, (int)timeout_watchdog_warn, good_servants);
}
- latency = t_now.tv_sec - t_last_restarted.tv_sec;
- if (servant_restart_interval > 0
- && latency > servant_restart_interval) {
- /* Restart all children every hour */
- clock_gettime(CLOCK_MONOTONIC, &t_last_restarted);
- servants_start();
+ for (s = servants_leader; s; s = s->next) {
+ int age = t_now.tv_sec - s->t_started.tv_sec;
+
+ if (age > servant_restart_interval) {
+ s->restarts = 0;
+ s->restart_blocked = 0;
+ }
+
+ if (servant_restart_count
+ && (s->restarts >= servant_restart_count)
+ && !s->restart_blocked) {
+ if (servant_restart_count > 1) {
+ cl_log(LOG_WARNING, "Max retry count reached: not restarting servant for %s",
+ s->devname);
+ }
+ s->restart_blocked = 1;
+ }
+
+ if (!s->restart_blocked) {
+ servant_start(s);
+ }
}
}
/* not reached */
@@ -802,15 +820,15 @@ int dump_headers(void)
{
int rc = 0;
struct servants_list_item *s = servants_leader;
- int devfd;
+ struct sbd_context *st;
for (s = servants_leader; s; s = s->next) {
fprintf(stdout, "==Dumping header on disk %s\n", s->devname);
- devfd = open_device(s->devname);
- if (devfd == -1)
+ st = open_device(s->devname);
+ if (!st)
return -1;
- rc = header_dump(devfd);
- close(devfd);
+ rc = header_dump(st);
+ close_device(st);
if (rc == -1)
return rc;
fprintf(stdout, "==Header on disk %s is dumped\n", s->devname);
@@ -835,10 +853,12 @@ int main(int argc, char **argv, char **envp)
get_uname();
- while ((c = getopt(argc, argv, "DRWhvw:d:n:1:2:3:4:5:t:")) != -1) {
+ while ((c = getopt(argc, argv, "DRTWZhvw:d:n:1:2:3:4:5:t:I:F:")) != -1) {
switch (c) {
case 'D':
- /* Ignore for historical reasons */
+ break;
+ case 'Z':
+ debug_mode++;
break;
case 'R':
skip_rt = 1;
@@ -879,6 +899,12 @@ int main(int argc, char **argv, char **envp)
case 't':
servant_restart_interval = atoi(optarg);
break;
+ case 'I':
+ timeout_io = atoi(optarg);
+ break;
+ case 'F':
+ servant_restart_count = atoi(optarg);
+ break;
case 'h':
usage();
return (0);
diff --git a/lib/stonith/sbd.h b/lib/stonith/sbd.h
index 001824b..1517760 100644
--- a/lib/stonith/sbd.h
+++ b/lib/stonith/sbd.h
@@ -15,8 +15,35 @@
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+
#include <arpa/inet.h>
+#include <asm/unistd.h>
+#include <clplumbing/cl_log.h>
+#include <clplumbing/cl_reboot.h>
+#include <clplumbing/coredumps.h>
+#include <clplumbing/realtime.h>
+#include <clplumbing/setproctitle.h>
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <libaio.h>
+#include <linux/fs.h>
+#include <linux/types.h>
+#include <linux/watchdog.h>
+#include <malloc.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <sys/ptrace.h>
+#include <sys/stat.h>
#include <sys/types.h>
+#include <sys/utsname.h>
+#include <sys/wait.h>
+#include <syslog.h>
+#include <time.h>
+#include <unistd.h>
/* Sector data types */
struct sector_header_s {
@@ -46,9 +73,17 @@ struct servants_list_item {
const char* devname;
pid_t pid;
int restarts;
+ int restart_blocked;
+ struct timespec t_last, t_started;
struct servants_list_item *next;
};
+struct sbd_context {
+ int devfd;
+ io_context_t ioctx;
+ struct iocb io;
+};
+
#define SBD_MSG_EMPTY 0x00
#define SBD_MSG_TEST 0x01
#define SBD_MSG_RESET 0x02
@@ -65,32 +100,33 @@ int watchdog_tickle(void);
int watchdog_init(void);
void sysrq_init(void);
void watchdog_close(void);
-int open_device(const char* devname);
+struct sbd_context *open_device(const char* devname);
+void close_device(struct sbd_context *st);
signed char cmd2char(const char *cmd);
void * sector_alloc(void);
const char* char2cmd(const char cmd);
-int sector_write(int devfd, int sector, const void *data);
-int sector_read(int devfd, int sector, void *data);
-int slot_read(int devfd, int slot, struct sector_node_s *s_node);
-int slot_write(int devfd, int slot, const struct sector_node_s *s_node);
-int mbox_write(int devfd, int mbox, const struct sector_mbox_s *s_mbox);
-int mbox_read(int devfd, int mbox, struct sector_mbox_s *s_mbox);
-int mbox_write_verify(int devfd, int mbox, const struct sector_mbox_s *s_mbox);
+int sector_write(struct sbd_context *st, int sector, const void *data);
+int sector_read(struct sbd_context *st, int sector, void *data);
+int slot_read(struct sbd_context *st, int slot, struct sector_node_s *s_node);
+int slot_write(struct sbd_context *st, int slot, const struct sector_node_s *s_node);
+int mbox_write(struct sbd_context *st, int mbox, const struct sector_mbox_s *s_mbox);
+int mbox_read(struct sbd_context *st, int mbox, struct sector_mbox_s *s_mbox);
+int mbox_write_verify(struct sbd_context *st, int mbox, const struct sector_mbox_s *s_mbox);
/* After a call to header_write(), certain data fields will have been
* converted to on-disk byte-order; the header should not be accessed
* afterwards anymore! */
-int header_write(int devfd, struct sector_header_s *s_header);
-int header_read(int devfd, struct sector_header_s *s_header);
+int header_write(struct sbd_context *st, struct sector_header_s *s_header);
+int header_read(struct sbd_context *st, struct sector_header_s *s_header);
int valid_header(const struct sector_header_s *s_header);
-struct sector_header_s * header_get(int devfd);
-int init_device(int devfd);
-int slot_lookup(int devfd, const struct sector_header_s *s_header, const char *name);
-int slot_unused(int devfd, const struct sector_header_s *s_header);
-int slot_allocate(int devfd, const char *name);
-int slot_list(int devfd);
-int slot_ping(int devfd, const char *name);
-int slot_msg(int devfd, const char *name, const char *cmd);
-int header_dump(int devfd);
+struct sector_header_s * header_get(struct sbd_context *st);
+int init_device(struct sbd_context *st);
+int slot_lookup(struct sbd_context *st, const struct sector_header_s *s_header, const char *name);
+int slot_unused(struct sbd_context *st, const struct sector_header_s *s_header);
+int slot_allocate(struct sbd_context *st, const char *name);
+int slot_list(struct sbd_context *st);
+int slot_ping(struct sbd_context *st, const char *name);
+int slot_msg(struct sbd_context *st, const char *name, const char *cmd);
+int header_dump(struct sbd_context *st);
void sysrq_trigger(char t);
void do_crashdump(void);
void do_reset(void);
@@ -105,10 +141,12 @@ extern unsigned long timeout_watchdog_warn;
extern int timeout_allocate;
extern int timeout_loop;
extern int timeout_msgwait;
+extern int timeout_io;
extern int watchdog_use;
extern int watchdog_set_timeout;
extern int skip_rt;
extern int debug;
+extern int debug_mode;
extern const char *watchdogdev;
extern char* local_uname;
@@ -133,18 +171,19 @@ int ping_via_slots(const char *name);
int dump_headers(void);
int check_all_dead(void);
+void servant_exit(void);
int servant(const char *diskname, const void* argp);
void recruit_servant(const char *devname, pid_t pid);
struct servants_list_item *lookup_servant_by_dev(const char *devname);
struct servants_list_item *lookup_servant_by_pid(pid_t pid);
void servants_kill(void);
void servants_start(void);
+void servant_start(struct servants_list_item *s);
void inquisitor_child(void);
int inquisitor(void);
int inquisitor_decouple(void);
int messenger(const char *name, const char *msg);
int check_timeout_inconsistent(void);
-void restart_servant_by_pid(pid_t pid);
void cleanup_servant_by_pid(pid_t pid);
int quorum_write(int good_servants);
int quorum_read(int good_servants);
diff --git a/logd/logd.in b/logd/logd.in
index cfb28b4..41d60c5 100755
--- a/logd/logd.in
+++ b/logd/logd.in
@@ -28,7 +28,7 @@
# Required-Start: $network $syslog $remote_fs
# Required-Stop: $network $syslog $remote_fs
# X-Start-Before: heartbeat openais corosync
-# Default-Start: 2 3 5
+# Default-Start: 3 5
# Default-Stop: 0 1 6
### END INIT INFO
@@ -87,11 +87,13 @@ case "$1" in
status) StatusLogd ;;
stop) StopLogd ;;
restart)
- sleeptime=1
+ sleeptime=1
$0 stop && sleep $sleeptime && $0 start
echo
;;
-
+ try-restart)
+ $0 status && $0 restart
+ ;;
*)
echo "Usage: $0 {start|stop|status|restart}"
exit 1
diff --git a/lrm/lrmd/lrmd.c b/lrm/lrmd/lrmd.c
index 88be04c..93b753f 100644
--- a/lrm/lrmd/lrmd.c
+++ b/lrm/lrmd/lrmd.c
@@ -1079,6 +1079,31 @@ emit_apphb(gpointer data)
return TRUE;
}
+static void
+calc_max_children()
+{
+#ifdef _SC_NPROCESSORS_ONLN
+ int nprocs;
+
+ nprocs = sysconf(_SC_NPROCESSORS_ONLN);
+ if( nprocs < 1 ) {
+ lrmd_log(LOG_WARNING, "%s: couldn't get the number of processors"
+ , __FUNCTION__);
+ } else {
+ if( nprocs/2 > max_child_count ) {
+ max_child_count = nprocs/2;
+ }
+ lrmd_log(LOG_INFO, "max-children set to %d "
+ "(%d processors online)", max_child_count, nprocs);
+ return;
+ }
+#else
+ lrmd_log(LOG_WARNING, "%s: cannot get the number of processors "
+ "on this platform", __FUNCTION__);
+#endif
+ lrmd_log(LOG_INFO, "max-children set to %d", max_child_count);
+}
+
/* main loop of the daemon*/
int
init_start ()
@@ -1105,6 +1130,8 @@ init_start ()
if( getenv("LRMD_MAX_CHILDREN") ) {
set_lrmd_param("max-children", getenv("LRMD_MAX_CHILDREN"));
+ } else {
+ calc_max_children();
}
qsort(msg_maps, MSG_NR, sizeof(struct msg_map), msg_type_cmp);
@@ -1574,7 +1601,6 @@ on_repeat_op_readytorun(gpointer data)
rsc->repeat_op_list = g_list_remove(rsc->repeat_op_list, op);
if (op->repeat_timeout_tag != 0) {
- Gmain_timeout_remove(op->repeat_timeout_tag);
op->repeat_timeout_tag = (guint)0;
}
@@ -2905,7 +2931,6 @@ rsc_execution_freeze_timeout(gpointer data)
}
if (rsc->delay_timeout > 0) {
- Gmain_timeout_remove(rsc->delay_timeout);
rsc->delay_timeout = (guint)0;
}
@@ -3472,6 +3497,9 @@ set_lrmd_param(const char *name, const char *value)
lrmd_log(LOG_ERR, "%s: invalid value for lrmd parameter %s"
, __FUNCTION__, name);
return HA_FAIL;
+ } else if (ival == max_child_count) {
+ lrmd_log(LOG_INFO, "max-children already set to %d", ival);
+ return HA_OK;
}
lrmd_log(LOG_INFO, "setting max-children to %d", ival);
max_child_count = ival;
diff --git a/lrm/lrmd/lrmd_fdecl.h b/lrm/lrmd/lrmd_fdecl.h
index d7f9a7e..9c97385 100644
--- a/lrm/lrmd/lrmd_fdecl.h
+++ b/lrm/lrmd/lrmd_fdecl.h
@@ -87,6 +87,7 @@ static int prepare_failmsg(struct ha_msg* msg,
static void async_notify(gpointer key, gpointer val, gpointer data);
static gboolean client_cmp_name(gpointer key, gpointer val, gpointer app_name);
static lrmd_client_t* lookup_client_by_name(char *app_name);
+static void calc_max_children(void);
/*
* following functions are used to monitor the exit of ra proc
diff --git a/lrm/test/Makefile.am b/lrm/test/Makefile.am
index 4b1c4fd..84f6657 100644
--- a/lrm/test/Makefile.am
+++ b/lrm/test/Makefile.am
@@ -42,7 +42,7 @@ callbacktest_LDADD = $(top_builddir)/lib/$(LRM_DIR)/liblrm.la
callbacktest_DEPENDENCIES = $(top_builddir)/lib/$(LRM_DIR)/liblrm.la
testdir = $(datadir)/$(PACKAGE_NAME)/lrmtest
-test_SCRIPTS = LRMBasicSanityCheck regression.sh evaltest.sh lrmregtest lrmregtest-heartbeat lrmregtest-lsb
+test_SCRIPTS = LRMBasicSanityCheck regression.sh evaltest.sh lrmregtest lrmregtest-lsb
test_DATA = README.regression defaults descriptions lrmadmin-interface language
# shouldn't need this, but we do for some versions of autofoo tools
EXTRA_DIST = $(test_SCRIPTS) $(test_DATA)
diff --git a/lrm/test/lrmregtest-heartbeat.in b/lrm/test/lrmregtest-heartbeat.in
deleted file mode 100644
index cc6fdca..0000000
--- a/lrm/test/lrmregtest-heartbeat.in
+++ /dev/null
@@ -1,17 +0,0 @@
-#!/bin/sh
-#
-# WARNING: This script is for LRM regressions tests only
-#
-
-. @HB_RA_DIR@/hto-mapfuncs
-
-case $# in
- 1) op=$1;;
- 2) export OCF_RESKEY_delay; OCF_RESKEY_delay=$1; op=$2;;
-esac
-
-OCF_TYPE=lrmregtest
-OCF_RESOURCE_INSTANCE=heartbeat
-export OCF_TYPE OCF_RESOURCE_INSTANCE
-
-ra_execocf $op
diff --git a/lrm/test/lrmregtest-lsb b/lrm/test/lrmregtest-lsb
new file mode 100644
index 0000000..4692b17
--- /dev/null
+++ b/lrm/test/lrmregtest-lsb
@@ -0,0 +1,54 @@
+#!/bin/sh
+#
+# WARNING: This script is for LRM regressions tests only
+#
+### BEGIN INIT INFO
+# Provides: lrmregtest
+# Required-Start:
+# Should-Start:
+# Required-Stop:
+# Should-Stop:
+# Default-Start:
+# Default-Stop:
+# Short-Description: LRM regression tests LSB RA
+# Description: LRM regression tests LSB RA
+### END INIT INFO
+
+TYPE=lrmregtest
+# depends on resource-agents and the OCF
+: ${OCF_ROOT:=/usr/lib/ocf}
+. ${OCF_ROOT}/lib/heartbeat/ocf-shellfuncs
+
+case "$1" in
+ start)
+ echo -n "Starting $TYPE"
+ ha_pseudo_resource lrmregtest_lsb start
+ ;;
+ stop)
+ echo -n "Shutting down $TYPE"
+ ha_pseudo_resource lrmregtest_lsb stop
+ ;;
+ status)
+ echo -n "Checking for $TYPE"
+ ha_pseudo_resource lrmregtest_lsb monitor
+ if [ $? -eq 0 ]; then
+ echo " running"
+ exit 0
+ else
+ echo " stopped"
+ exit 3
+ fi
+ ;;
+ *)
+ echo "Usage: $0 {start|stop|status}"
+ exit 1
+ ;;
+esac
+
+if [ $? -eq 0 ]; then
+ echo " OK"
+ exit 0
+else
+ echo " failed"
+ exit 1
+fi
diff --git a/lrm/test/lrmregtest-lsb.in b/lrm/test/lrmregtest-lsb.in
deleted file mode 100644
index 1d47cd3..0000000
--- a/lrm/test/lrmregtest-lsb.in
+++ /dev/null
@@ -1,12 +0,0 @@
-#!/bin/sh
-#
-# WARNING: This script is for LRM regressions tests only
-#
-
-. @HB_RA_DIR@/hto-mapfuncs
-
-OCF_TYPE=lrmregtest
-OCF_RESOURCE_INSTANCE=lsb
-export OCF_TYPE OCF_RESOURCE_INSTANCE
-
-ra_execocf $1
diff --git a/lrm/test/regression.sh.in b/lrm/test/regression.sh.in
index 19a8ffe..550321e 100755
--- a/lrm/test/regression.sh.in
+++ b/lrm/test/regression.sh.in
@@ -41,7 +41,6 @@ DIFF_OPTS="--ignore-all-space -U 1"
common_filter=$TESTDIR/common.filter
common_exclf=$TESTDIR/common.excl
OCF_RA=$OCF_ROOT/resource.d/heartbeat/lrmregtest
-HB_RA=@HB_RA_DIR@/lrmregtest
LSB_RA=@LSB_RA_DIR@/lrmregtest
export OUTDIR TESTDIR LRMADMIN
@@ -153,26 +152,13 @@ stop_lrmd() {
$HA_BIN/lrmd -k
}
cp_ra() {
- if [ ! -e $OCF_RA ]; then
- cp -p lrmregtest $OCF_RA
- lrmregtest_ocf=1
- fi
+ cp -p lrmregtest $OCF_RA
chmod +x $OCF_RA
- if [ ! -e $LSB_RA ]; then
- cp -p lrmregtest-lsb $LSB_RA
- lrmregtest_lsb=1
- fi
+ cp -p lrmregtest-lsb $LSB_RA
chmod +x $LSB_RA
- if [ ! -e $HB_RA ]; then
- cp -p lrmregtest-heartbeat $HB_RA
- lrmregtest_heartbeat=1
- fi
- chmod +x $HB_RA
}
rm_ra() {
- [ "$lrmregtest_ocf" ] && rm -f $OCF_RA
- [ "$lrmregtest_lsb" ] && rm -f $LSB_RA
- [ "$lrmregtest_heartbeat" ] && rm -f $HB_RA
+ rm -f $OCF_RA $LSB_RA
}
cp_ra
diff --git a/lrm/test/testcases/rscexec b/lrm/test/testcases/rscexec
index a6770ad..e118ae1 100644
--- a/lrm/test/testcases/rscexec
+++ b/lrm/test/testcases/rscexec
@@ -15,21 +15,6 @@ exec operation=stop
exec operation=monitor
exec operation=meta-data
del
-# heartbeat
-%setenv dflt_class=heartbeat dftl_rsc=rscexec_rsc_r1-heartbeat
-add args=0
-exec operation=start
-state
-exec operation=monitor
-exec operation=start
-exec operation=monitor
-exec operation=stop
-state
-exec operation=monitor
-exec operation=stop
-exec operation=monitor
-exec operation=meta-data
-del
# lsb
%setenv dflt_class=lsb dftl_rsc=rscexec_rsc_r1-lsb
add
diff --git a/lrm/test/testcases/rscexec.exp b/lrm/test/testcases/rscexec.exp
index a90da79..71bdc2e 100644
--- a/lrm/test/testcases/rscexec.exp
+++ b/lrm/test/testcases/rscexec.exp
@@ -61,64 +61,6 @@ The resource 3 operations' information:
.TRY Delete resource rscexec_rsc_r1
Succeeded in deleting this resource.
-.SETENV dflt_class=heartbeat dftl_rsc=rscexec_rsc_r1-heartbeat
-.TRY Add resource rscexec_rsc_r1 class=heartbeat type=lrmregtest provider=heartbeat args=0
-Succeeded in adding this resource.
-.TRY Exec rscexec_rsc_r1 op=start timeout=1000 interval=0 target=EVERYTIME args=
-> start succeed (status=0,rc=0): [null]
-
-.TRY Show state rscexec_rsc_r1
-resource state:LRM_RSC_IDLE
-The resource 1 operations' information:
- operation 'start' [call_id=(removed)]:
- start_delay=0, interval=0, timeout=1000, app_name=lrmadmin
- rc=0 (ok), op_status=0 (succeed)
- parameters: 1=0
-.TRY Exec rscexec_rsc_r1 op=monitor timeout=1000 interval=0 target=EVERYTIME args=
-
-> monitor succeed (status=0,rc=0): INFO: Running OK
-
-.TRY Exec rscexec_rsc_r1 op=start timeout=1000 interval=0 target=EVERYTIME args=
-> start succeed (status=0,rc=0): [null]
-
-.TRY Exec rscexec_rsc_r1 op=monitor timeout=1000 interval=0 target=EVERYTIME args=
-
-> monitor succeed (status=0,rc=0): INFO: Running OK
-
-.TRY Exec rscexec_rsc_r1 op=stop timeout=1000 interval=0 target=EVERYTIME args=
-> stop succeed (status=0,rc=0): [null]
-
-.TRY Show state rscexec_rsc_r1
-resource state:LRM_RSC_IDLE
-The resource 3 operations' information:
- operation 'start' [call_id=(removed)]:
- start_delay=0, interval=0, timeout=1000, app_name=lrmadmin
- rc=0 (ok), op_status=0 (succeed)
- parameters: 1=0
- operation 'monitor' [call_id=(removed)]:
- start_delay=0, interval=0, timeout=1000, app_name=lrmadmin
- rc=0 (ok), op_status=0 (succeed)
- parameters: 1=0
- operation 'stop' [call_id=(removed)]:
- start_delay=0, interval=0, timeout=1000, app_name=lrmadmin
- rc=0 (ok), op_status=0 (succeed)
- parameters: 1=0
-.TRY Exec rscexec_rsc_r1 op=monitor timeout=1000 interval=0 target=EVERYTIME args=
-
-> monitor succeed (status=0,rc=7): INFO: Resource is stopped
-
-.TRY Exec rscexec_rsc_r1 op=stop timeout=1000 interval=0 target=EVERYTIME args=
-> stop succeed (status=0,rc=0): [null]
-
-.TRY Exec rscexec_rsc_r1 op=monitor timeout=1000 interval=0 target=EVERYTIME args=
-
-> monitor succeed (status=0,rc=7): INFO: Resource is stopped
-
-.TRY Exec rscexec_rsc_r1 op=meta-data timeout=1000 interval=0 target=EVERYTIME args=
-> meta-data succeed (status=0,rc=0): [null]
-
-.TRY Delete resource rscexec_rsc_r1
-Succeeded in deleting this resource.
.SETENV dflt_class=lsb dftl_rsc=rscexec_rsc_r1-lsb
.TRY Add resource rscexec_rsc_r1 class=lsb type=lrmregtest provider=heartbeat args=
Succeeded in adding this resource.
diff --git a/lrm/test/testcases/rscmgmt b/lrm/test/testcases/rscmgmt
index d4337d5..8d745d3 100644
--- a/lrm/test/testcases/rscmgmt
+++ b/lrm/test/testcases/rscmgmt
@@ -10,18 +10,13 @@ list
add rsc=r1
list
del rsc=r1
-%setenv dflt_class=heartbeat dflt_type=lrmregtest
-list
-add rsc=r1
-list
-del rsc=r1
list
#
# a bit of mix
#
%setenv dflt_class=ocf
add rsc=r1
-add rsc=r1 class=heartbeat type=lrmregtest
+add rsc=r1 class=lsb type=lrmregtest
add rsc=r1
del rsc=r1
add rsc=r1 class=lsb type=lrmregtest
diff --git a/lrm/test/testcases/rscmgmt.exp b/lrm/test/testcases/rscmgmt.exp
index 6d257e4..3a5c4bf 100644
--- a/lrm/test/testcases/rscmgmt.exp
+++ b/lrm/test/testcases/rscmgmt.exp
@@ -29,25 +29,12 @@ Resource agent type:lrmregtest
Resource agent provider:heartbeat
.TRY Delete resource r1
Succeeded in deleting this resource.
-.SETENV dflt_class=heartbeat dflt_type=lrmregtest
-.TRY List resources
-Currently no resources are managed by LRM.
-.TRY Add resource r1 class=heartbeat type=lrmregtest provider=heartbeat args=
-Succeeded in adding this resource.
-.TRY List resources
-
-Resource ID:r1
-Resource agent class:heartbeat
-Resource agent type:lrmregtest
-Resource agent provider:heartbeat
-.TRY Delete resource r1
-Succeeded in deleting this resource.
.TRY List resources
Currently no resources are managed by LRM.
.SETENV dflt_class=ocf
.TRY Add resource r1 class=ocf type=lrmregtest provider=heartbeat args=
Succeeded in adding this resource.
-.TRY Add resource r1 class=heartbeat type=lrmregtest provider=heartbeat args=
+.TRY Add resource r1 class=lsb type=lrmregtest provider=heartbeat args=
ERROR: lrm_add_rsc(): got a return code HA_FAIL from a reply message of addrsc with function get_ret_from_msg.
Failed to add this resource.
.TRY Add resource r1 class=ocf type=lrmregtest provider=heartbeat args=
diff --git a/lrm/test/testcases/xmllint.sh b/lrm/test/testcases/xmllint.sh
index 5f34721..f61288c 100755
--- a/lrm/test/testcases/xmllint.sh
+++ b/lrm/test/testcases/xmllint.sh
@@ -7,7 +7,7 @@ function chkoutput(ra) {
if( close(XMLLINT) ) # we need gawk for this
print "xmllint reported error in RA:",ra;
}
-many=="many" && /^[a-zA-Z][^:]*:[a-z]+$/ {
+many=="many" && /^[a-zA-Z][^:]*:[a-zA-Z0-9]+$/ {
chkoutput(ra);
ra=$0;
next;
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-ha/cluster-glue.git
More information about the Debian-HA-Commits
mailing list