Decouple Guest-server/agent from stx-metal

This decouples the build and packaging of guest-server, guest-agent from
mtce, by splitting guest component into stx-nfv repo.

This leaves existing C++ code, scripts, and resource files untouched,
so there is no functional change. Code refactoring is beyond the scope
of this update.

Makefiles were modified to include devel headers directories
/usr/include/mtce-common and /usr/include/mtce-daemon.
This ensures there is no contamination with other system headers.

The cgts-mtce-common package is renamed and split into:
- repo stx-metal: mtce-common, mtce-common-dev
- repo stx-metal: mtce
- repo stx-nfv: mtce-guest
- repo stx-ha: updates package dependencies to mtce-pmon for
  service-mgmt, sm, and sm-api

mtce-common:
- contains common and daemon shared source utility code

mtce-common-dev:
- based on mtce-common, contains devel package required to build
  mtce-guest and mtce
- contains common library archives and headers

mtce:
- contains components: alarm, fsmon, fsync, heartbeat, hostw, hwmon,
  maintenance, mtclog, pmon, public, rmon

mtce-guest:
- contains guest component guest-server, guest-agent

Story: 2002829
Task: 22748

Change-Id: I9c7a9b846fd69fd566b31aa3f12a043c08f19f1f
Signed-off-by: Jim Gauld <james.gauld@windriver.com>
This commit is contained in:
Jim Gauld 2018-09-18 12:05:27 -04:00
parent eb7559f335
commit 6a5e10492c
321 changed files with 456 additions and 11829 deletions

View File

@ -2,14 +2,12 @@
# If these have dependencies, they will be pulled in automatically
#
# cgts-mtce-common
cgts-mtce-common
cgts-mtce-common-pmon
cgts-mtce-common-rmon
cgts-mtce-common-hwmon
cgts-mtce-common-guestAgent
cgts-mtce-common-guestServer
cgts-mtce-common-hostw
# mtce
mtce
mtce-pmon
mtce-rmon
mtce-hwmon
mtce-hostw
# cgts-mtce-compute
cgts-mtce-compute

View File

@ -1,4 +1,5 @@
mtce-common
mtce
mtce-compute
mtce-control
mtce-storage

View File

@ -1,5 +1,5 @@
Metadata-Version: 1.1
Name: cgts-mtce-common
Name: mtce-common
Version: 1.0
Summary: Titanium Cloud Platform Common Node Maintenance Package
Home-page:
@ -7,10 +7,7 @@ Author: Windriver
Author-email: info@windriver.com
License: Apache-2.0
Description: Maintenance common package containing host maintenace and heartbeat
agent/client daemons as well as the hardware and process monitor
daemons, hardware watchdog process, guest heartbeat agent/client
daemons, resource and file system daemons as well as initialization
and support files for each.
Description: Maintenance common package containing shared utility code between
mtce and mtce-guest.
Platform: UNKNOWN

View File

@ -1,3 +1,3 @@
SRC_DIR="cgts-mtce-common-1.0"
TIS_PATCH_VER=138
SRC_DIR="src"
TIS_PATCH_VER=139
BUILD_IS_SLOW=5

View File

@ -0,0 +1,154 @@
Summary: Titanuim Cloud Maintenance Common Base Package
Name: mtce-common
Version: 1.0
Release: %{tis_patch_ver}%{?_tis_dist}
License: Apache-2.0
Group: base
Packager: Wind River <info@windriver.com>
URL: unknown
Source0: %{name}-%{version}.tar.gz
BuildRequires: libssh2
BuildRequires: libssh2-devel
BuildRequires: json-c
BuildRequires: json-c-devel
BuildRequires: fm-common
BuildRequires: fm-common-dev
BuildRequires: openssl
BuildRequires: openssl-devel
BuildRequires: libevent
BuildRequires: libevent-devel
BuildRequires: fm-mgr
BuildRequires: expect
BuildRequires: postgresql
BuildRequires: libuuid-devel
BuildRequires: guest-client-devel
BuildRequires: systemd-devel
BuildRequires: cppcheck
Requires: util-linux
Requires: /bin/bash
Requires: /bin/systemctl
Requires: dpkg
Requires: time
Requires: libevent-2.0.so.5()(64bit)
Requires: expect
Requires: libfmcommon.so.1()(64bit)
Requires: libstdc++.so.6(GLIBCXX_3.4.14)(64bit)
Requires: libstdc++.so.6(GLIBCXX_3.4.9)(64bit)
Requires: fm-common >= 1.0
Requires: libc.so.6(GLIBC_2.2.5)(64bit)
Requires: libstdc++.so.6(GLIBCXX_3.4.11)(64bit)
Requires: /bin/sh
Requires: librt.so.1()(64bit)
Requires: libc.so.6(GLIBC_2.3)(64bit)
Requires: libc.so.6(GLIBC_2.14)(64bit)
Requires: libjson-c.so.2()(64bit)
Requires: libpthread.so.0(GLIBC_2.2.5)(64bit)
Requires: librt.so.1(GLIBC_2.3.3)(64bit)
Requires: libgcc_s.so.1(GCC_3.0)(64bit)
Requires: libstdc++.so.6(CXXABI_1.3)(64bit)
Requires: libevent >= 2.0.21
Requires: librt.so.1(GLIBC_2.2.5)(64bit)
Requires: libuuid.so.1()(64bit)
Requires: libm.so.6()(64bit)
Requires: rtld(GNU_HASH)
Requires: libstdc++.so.6()(64bit)
Requires: libc.so.6(GLIBC_2.4)(64bit)
Requires: libc.so.6()(64bit)
Requires: libssh2.so.1()(64bit)
Requires: libgcc_s.so.1()(64bit)
Requires: libstdc++.so.6(GLIBCXX_3.4)(64bit)
Requires: libstdc++.so.6(GLIBCXX_3.4.15)(64bit)
Requires: libpthread.so.0()(64bit)
Requires: /usr/bin/expect
Requires: python-rtslib
%description
Summary: Titanuim Cloud Maintenance Common Base Package
%package -n mtce-common-dev
Summary: Titanuim Cloud Maintenance Common Base - Development files
Group: devel
Provides: mtce-common-dev = %{version}-%{release}
%description -n mtce-common-dev
Titanuim Cloud Maintenance Common Base. This package contains header files,
and related items necessary for software development.
# Disable debuginfo for mtce-common. This package is not included in the
# target ISO, and does not contain binaries. This directive prevents the
# utility find-debugfiles.sh from failing if it cannot find debuginfo files.
%define debug_package %{nil}
%prep
%setup
%build
VER=%{version}
MAJOR=$(echo $VER | awk -F . '{print $1}')
MINOR=$(echo $VER | awk -F . '{print $2}')
make MAJOR=$MAJOR MINOR=$MINOR %{?_smp_mflags} build
%global _buildsubdir %{_builddir}/%{name}-%{version}
%install
rm -v -rf $RPM_BUILD_ROOT
VER=%{version}
MAJOR=$(echo $VER | awk -F . '{print $1}')
MINOR=$(echo $VER | awk -F . '{print $2}')
install -m 755 -d %{buildroot}%{_libdir}
install -m 644 -p -D %{_buildsubdir}/daemon/libdaemon.a %{buildroot}%{_libdir}
install -m 644 -p -D %{_buildsubdir}/common/libcommon.a %{buildroot}%{_libdir}
install -m 644 -p -D %{_buildsubdir}/common/libthreadUtil.a %{buildroot}%{_libdir}
install -m 644 -p -D %{_buildsubdir}/common/libipmiUtil.a %{buildroot}%{_libdir}
install -m 644 -p -D %{_buildsubdir}/common/libpingUtil.a %{buildroot}%{_libdir}
install -m 644 -p -D %{_buildsubdir}/common/libnodeBase.a %{buildroot}%{_libdir}
install -m 644 -p -D %{_buildsubdir}/common/libregexUtil.a %{buildroot}%{_libdir}
install -m 644 -p -D %{_buildsubdir}/common/libhostUtil.a %{buildroot}%{_libdir}
# mtce-common headers required to bring in nodeBase.h
install -m 755 -d %{buildroot}%{_includedir}
install -m 755 -d %{buildroot}%{_includedir}/mtce-common
install -m 644 -p -D %{_buildsubdir}/common/fitCodes.h %{buildroot}%{_includedir}/mtce-common
install -m 644 -p -D %{_buildsubdir}/common/logMacros.h %{buildroot}%{_includedir}/mtce-common
install -m 644 -p -D %{_buildsubdir}/common/returnCodes.h %{buildroot}%{_includedir}/mtce-common
install -m 644 -p -D %{_buildsubdir}/common/nodeTimers.h %{buildroot}%{_includedir}/mtce-common
# mtce-common headers required to build mtce-guest
install -m 644 -p -D %{_buildsubdir}/common/hostClass.h %{buildroot}%{_includedir}/mtce-common
install -m 644 -p -D %{_buildsubdir}/common/httpUtil.h %{buildroot}%{_includedir}/mtce-common
install -m 644 -p -D %{_buildsubdir}/common/jsonUtil.h %{buildroot}%{_includedir}/mtce-common
install -m 644 -p -D %{_buildsubdir}/common/msgClass.h %{buildroot}%{_includedir}/mtce-common
install -m 644 -p -D %{_buildsubdir}/common/nodeBase.h %{buildroot}%{_includedir}/mtce-common
install -m 644 -p -D %{_buildsubdir}/common/nodeEvent.h %{buildroot}%{_includedir}/mtce-common
install -m 644 -p -D %{_buildsubdir}/common/nodeMacro.h %{buildroot}%{_includedir}/mtce-common
install -m 644 -p -D %{_buildsubdir}/common/nodeUtil.h %{buildroot}%{_includedir}/mtce-common
install -m 644 -p -D %{_buildsubdir}/common/timeUtil.h %{buildroot}%{_includedir}/mtce-common
# mtce-daemon headers required to build mtce-guest
install -m 755 -d %{buildroot}%{_includedir}/mtce-daemon
install -m 644 -p -D %{_buildsubdir}/daemon/daemon_ini.h %{buildroot}%{_includedir}/mtce-daemon
install -m 644 -p -D %{_buildsubdir}/daemon/daemon_common.h %{buildroot}%{_includedir}/mtce-daemon
install -m 644 -p -D %{_buildsubdir}/daemon/daemon_option.h %{buildroot}%{_includedir}/mtce-daemon
# remaining mtce-common headers required to build mtce
install -m 644 -p -D %{_buildsubdir}/common/alarmUtil.h %{buildroot}%{_includedir}/mtce-common
install -m 644 -p -D %{_buildsubdir}/common/hostUtil.h %{buildroot}%{_includedir}/mtce-common
install -m 644 -p -D %{_buildsubdir}/common/ipmiUtil.h %{buildroot}%{_includedir}/mtce-common
install -m 644 -p -D %{_buildsubdir}/common/nlEvent.h %{buildroot}%{_includedir}/mtce-common
install -m 644 -p -D %{_buildsubdir}/common/pingUtil.h %{buildroot}%{_includedir}/mtce-common
install -m 644 -p -D %{_buildsubdir}/common/regexUtil.h %{buildroot}%{_includedir}/mtce-common
install -m 644 -p -D %{_buildsubdir}/common/threadUtil.h %{buildroot}%{_includedir}/mtce-common
install -m 644 -p -D %{_buildsubdir}/common/tokenUtil.h %{buildroot}%{_includedir}/mtce-common
%clean
rm -v -rf $RPM_BUILD_ROOT
%post
%files -n mtce-common-dev
%defattr(-,root,root,-)
%{_includedir}/mtce-common/*.h
%{_includedir}/mtce-daemon/*.h
%{_libdir}/*.a

View File

@ -1,47 +0,0 @@
#
# Copyright (c) 2013-2016 Wind River Systems, Inc.
#
# SPDX-License-Identifier: Apache-2.0
#
VER=1
VER_MJR=1
build:
@(cd public ; make lib VER=$(VER) VER_MJR=$(VER_MJR))
@(cd rmon/rmonApi ; make lib VER=$(VER) VER_MJR=$(VER_MJR))
@(cd daemon ; make lib VER=$(VER) VER_MJR=$(VER_MJR))
@(cd common ; make lib fsync VER=$(VER) VER_MJR=$(VER_MJR))
@(cd alarm ; make build VER=$(VER) VER_MJR=$(VER_MJR))
@(cd heartbeat ; make build VER=$(VER) VER_MJR=$(VER_MJR))
@(cd maintenance ; make build VER=$(VER) VER_MJR=$(VER_MJR))
@(cd hwmon ; make build VER=$(VER) VER_MJR=$(VER_MJR))
@(cd mtclog ; make build VER=$(VER) VER_MJR=$(VER_MJR))
@(cd pmon ; make build VER=$(VER) VER_MJR=$(VER_MJR))
@(cd guest ; make build VER=$(VER) VER_MJR=$(VER_MJR))
@(cd fsmon ; make build VER=$(VER) VER_MJR=$(VER_MJR))
@(cd rmon ; make build VER=$(VER) VER_MJR=$(VER_MJR))
@(cd rmon/rmon_resource_notify ; make build VER=$(VER) VER_MJR=$(VER_MJR))
@(cd hostw ; make build VER=$(VER) VER_MJR=$(VER_MJR))
clean:
@( cd public ; make clean )
@( cd rmon/rmonApi ; make clean )
@( cd daemon ; make clean )
@( cd common ; make clean )
@( cd alarm ; make clean )
@( cd mtclog ; make clean )
@( cd hwmon ; make clean )
@( cd pmon ; make clean )
@( cd guest ; make clean )
@( cd fsmon ; make clean )
@( cd heartbeat ; make clean )
@( cd maintenance ; make clean )
@( cd rmon ; make clean )
@( cd rmon/rmon_resource_notify ; make clean )
@( cd hostw ; make clean )
@( rm -rf release )
backup: clean
mkdir -p ~/mtce
cp -a * ~/mtce

View File

@ -1,48 +0,0 @@
#
# Copyright (c) 2015-2016 Wind River Systems, Inc.
#
# SPDX-License-Identifier: Apache-2.0
#
SRCS = guestClass.cpp guestInstClass.cpp \
guestSvrFsm.cpp guestSvrHdlr.cpp \
guestServer.cpp guestAgent.cpp \
guestHttpSvr.cpp guestHttpUtil.cpp guestVimApi.cpp \
guestUtil.cpp guestSvrUtil.cpp guestSvrMsg.cpp \
guestVirtio.cpp guestStubs.cpp
AGENT_OBJS = \
guestAgent.o guestClass.o guestHttpSvr.o guestHttpUtil.o guestVimApi.o guestUtil.o guestStubs.o
SERVER_OBJS = \
guestServer.o guestInstClass.o \
guestSvrFsm.o guestSvrHdlr.o \
guestSvrMsg.o guestVirtio.o \
guestUtil.o guestSvrUtil.o
OBJS = $(SRCS:.cpp=.o)
CCPFLAGS = -g -O2 -Wall -Wextra -Werror
LDLIBS = -lstdc++ -ldaemon -lcommon -lfmcommon -ljson-c -levent -lrt -lcrypto -luuid
INCLUDES = -I../daemon -I../common -I../maintenance -I. -I..
#CFLAGS = -fPIC -g -O2 -Wall -Wextra -Werror -I../daemon -I../common -I. -I..
#.cpp.o:
# $(CXX) $(INCLUDES) $(CCPFLAGS) $(EXTRACCFLAGS) -c $< -o $@
build: $(OBJS)
$(CXX) $(CCPFLAGS) $(AGENT_OBJS) -L../daemon -L../common -L../public -L.. $(LDLIBS) -o guestAgent
$(CXX) $(CCPFLAGS) $(SERVER_OBJS) -L../libs -L../daemon -L../common -L../public -L.. $(LDLIBS) -L. -o guestServer
#$(CXX) $(CCPFLAGS) $(SERVER_OBJS) -L../libs -L../daemon -L../common -L../public -L.. $(LDLIBS) -L. -ltrap_handler -lalarm_clock -latomic -o guestServer
.cpp.o:
$(CXX) $(INCLUDES) $(CCPFLAGS) $(EXTRACCFLAGS) -c $< -o $@
common:
( cd ../common ; make clean ; make lib VER=$(VER) VER_MJR=$(VER_MJR))
daemon:
( cd ../daemon ; make clean ; make lib VER=$(VER) VER_MJR=$(VER_MJR))
clean:
@rm -f $(OBJ) guestAgent guestServer *.o *.a libghbb.so.1

View File

@ -1,84 +0,0 @@
This maintenance common guest service was introduced in cgts release 2 in order to
provide a means of guest heartbeat orchistration under VIM (system management) control.
This module includes header files exported to the sysroot by the original cgts
release 1 heartbeat service for messaging structure definition.
That original module builds a common heartbeat daemon capable of running on the
controller, compute and within the vm. The controller version did nothing except
for respond to heartbeats from the compute version. The compute instance was the
brains of the heartbeat service reponsible for starting heartbeat to the VMs and
interfacing with Nova to take actions.
The introduction of this module changes a large part of that.
Here is a summary of the changes
1. Packaging and Initialization:
The source code for the original cgts release 1 heartbeat daemon remains
unchanged but the packaging of the heartbeat daemon and heartbeat_init
script are modified
a. image.inc and filter_out packaging files are modified to exclude the
heartbeat daemon from being packaged on the controller.
b. because the heartbeat daemon is still packaged on the compute
heartbeat_init script is modified to prevent the heartbeat
daemon from being spawned on the compute host.
Note: the heartbeat daemon continues to be packaged and spawned in the guest
as it did in release 1 - no change there.
2. Compute Function: Heartbeats the guest and reports failures.
Package: cgts-mtce-common-guestServer-1.0-r54.0.x86_64.rpm
Binary: /usr/local/bin/guestServer
Init: /etc/init.d/guestServer
Managed: /etc/pmon.d/guestServer.pmon
3. Controller Function: Guest heartbeat control and event proxy
Package: cgts-mtce-common-guestAgent-x.x-rxx.x86_64.rpm
Binary: /usr/local/bin/guestAgent
Init: /usr/lib/ocf/resource.d/platform/guestAgent
Managed: by SM
The heartbeat daemon that did run on the controller is replaced by a new
guestAgent daemon performing the following functions
a. HTTP Command Receiver : to which the VIM sends instance control commands.
b. HTTP Event Transmitter: to which the daemon can send instance failure
events and state query commands to the VIM.
c. State query audit to the
Behavioral Executive Summary:
The guestServer daemon (on the compute) listens for (using inotify) 'uuid'
UNIX named heartbeat communication channels that nova:libvirt creates and
opens in /var/lib/libvirt/qemu whenever an instance is created. Example:
/var/lib/libvirt/qemu/cgcs.heartbeat.02e172a9-aeae-4cef-a6bc-7eb9de7825d6.sock
The guestServer connects (and auto reconnects) to these channels when they are
created or modified and disconnects from them when deleted.
Once connected, the guestServer listens for TCP messages over that UNIX named
socket.
If a guest supports heartbeating then it will run the heartbeat_init script
during its initialization process. Once the heartbeat daemon is running it
will periodically send init request messages to the libvirt pipe that,
on the host side, the guestServer is listening for.
on receipt of an init message, the guestServer will extract name, timeout
and corrective action info from it and then send back an 'init_ack' followed
by a continuous heartbeat cycle consisting of sending a 'challenge' request
messages and expecting a correct computational responses within a guest specified
heartbeat window. Failure to comply will result in a corrective action that was
specified in the init message from the guest.
The VIM is responsible for enabling and disabling heartbeat fault reporting as
well as taking the guest specified corrective action in he event of a heartbeat
failure.
The VIM guestAgent running

File diff suppressed because it is too large Load Diff

View File

@ -1,319 +0,0 @@
#ifndef __INCLUDE_GUESTBASE_H__
#define __INCLUDE_GUESTBASE_H__
/*
* Copyright (c) 2013-2016 Wind River Systems, Inc.
*
* SPDX-License-Identifier: Apache-2.0
*
*/
/**
* @file
* Wind River CGTS Platform Guest Services "Base" Header
*/
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <netdb.h>
#include <unistd.h>
#include <time.h>
#include <sys/time.h>
#include <signal.h>
#include <list>
#include <guest-client/guest_heartbeat_msg_defs.h>
using namespace std;
#include "msgClass.h"
#include "nodeBase.h"
#include "httpUtil.h"
#include "nodeTimers.h"
#define WANT_NEW
/**
* @addtogroup guest_services_base
* @{
*/
#ifdef __AREA__
#undef __AREA__
#endif
#define __AREA__ "gst"
#define CONFIG_CLIENT_RX_PORT (0x00000001)
#define CONFIG_MTC_EVENT_PORT (0x00000002)
#define CONFIG_MTC_CMD_PORT (0x00000004)
#define CONFIG_AGENT_RX_PORT (0x00000008)
#define CONFIG_VIM_CMD_RX_PORT (0x00000010)
#define CONFIG_VIM_EVENT_RX_PORT (0x00000020)
#define HB_DEFAULT_FIRST_MS 2000
#define HB_DEFAULT_INTERVAL_MS 1000
#define HB_DEFAULT_REBOOT_MS 10000
#define HB_DEFAULT_VOTE_MS 10000
#define HB_DEFAULT_SHUTDOWN_MS 10000
#define HB_DEFAULT_SUSPEND_MS 10000
#define HB_DEFAULT_RESUME_MS 10000
#define HB_DEFAULT_RESTART_MS 120000
/* Directory where libvirt creates the serial I/O pipe channel sockets into the guest
* We monitor this directory with inotify for file changes */
#define QEMU_CHANNEL_DIR ((const char *)"/var/lib/libvirt/qemu")
#define ARRAY_SIZE(x) ((int)(sizeof(x)/sizeof(*x)))
#define MAX_INSTANCES (100)
#define MAX_MESSAGES (10)
/* The socket select timeout */
#define GUEST_SOCKET_TO (10000)
#define DEFAULT_CONNECT_WAIT (1)
#define CONNECT_TIMOUT (60)
#define WAIT_FOR_INIT_TIMEOUT (60)
#define HEARTBEAT_START_TIMEOUT (120)
#define SEARCH_AUDIT_TIME (180)
void guestTimer_handler ( int sig, siginfo_t *si, void *uc);
const char * get_guest_msg_hdr (void) ;
typedef struct
{
char buffer [256];
} gst_message_type ;
typedef enum
{
hbs_invalid,
hbs_server_waiting_init,
hbs_server_waiting_challenge,
hbs_server_waiting_response,
hbs_server_paused, // heartbeat paused at request of vm
hbs_server_nova_paused, // heartbeat paused at request of nova
hbs_server_migrating, // heartbeat paused while migrate in progress
hbs_server_corrective_action,
hbs_client_waiting_init_ack,
hbs_client_waiting_challenge,
hbs_client_waiting_pause_ack,
hbs_client_waiting_resume_ack,
hbs_client_paused,
hbs_client_waiting_shutdown_ack,
hbs_client_waiting_shutdown_response,
hbs_client_shutdown_response_recieved,
hbs_client_exiting,
hbs_state_max
} hb_state_t;
/** Guest service control messaging socket control structure */
typedef struct
{
/** Guest Services Messaging Agent Receive (from guestServer) Socket
*
* Note: This socket supports receiving from the computes specifying
* either the floating or local IP */
int agent_rx_port ;
msgClassSock* agent_rx_float_sock ;
msgClassSock* agent_rx_local_sock ;
/** Guest Services Messaging Agent Transmit (to guestServer) Socket
*
* Note: This transmit socket can be used for any port
* specified at send time */
msgClassSock* agent_tx_sock ;
/** Guest Services Messaging Socket mtcAgent commands are received on */
msgClassSock* mtc_cmd_sock ;
int mtc_cmd_port ;
/** Guest Services Messaging Server Receive (from guestAgent) Socket */
msgClassSock* server_rx_sock ;
int server_rx_port ;
/** Guest Services Messaging Server Transmit (to guestAgent) Socket */
msgClassSock* server_tx_sock ;
struct sockaddr_in server_tx_addr ;
/** Socket used to transmit READY status and Events to Maintenance */
int mtc_event_tx_port ;
msgClassSock* mtc_event_tx_sock ;
int netlink_sock ; /* netlink socket */
int ioctl_sock ; /* general ioctl socket */
msgSock_type mtclogd ;
} guest_services_socket_type ;
/**
* The HTTP server supports two URL levels ;
* a hosts level and instances level.
**/
typedef enum
{
SERVICE_LEVEL_NONE,
SERVICE_LEVEL_HOST,
SERVICE_LEVEL_INST,
} service_level_enum ;
/** common service_type control info */
typedef struct
{
bool provisioned ; /* set true once the VIM issues create */
string state ; /* enabled, configured or disabled */
bool reporting ; /* failue reporting state */
int failures ; /* Running count of failures */
bool failed ; /* true means heartbeating has failed */
bool waiting ; /* Waiting on a response */
int b2b_misses ; /* running back-to-back misses */
} service_type ;
/** A grouping of info extracted from command's url */
typedef struct
{
service_level_enum service_level ;
string uuid ;
string command ;
string temp ;
} url_info_type ;
/** instance control structure */
typedef struct
{
string hostname ; /**< The host that this instance is on */
/* Instance identifiers */
string name ; /**< the Instance Name as it appears in the GUI */
string uuid ; /**< the instance uuid which is unique to the system */
string chan ; /**< virtio channel name 'cgcs.heartbeat.<uuid>.sock' */
string inst ; /**< the instance part of the channel name */
/* Set to true when this channel has been provisioned by the guestAgent */
// bool provisioned ;
/*
* Full path and name to the detected channel.
* Used to set inotify file watch.
*/
string fd_namespace ;
#define CHAN_FLAGS (SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC )
int chan_fd ;
bool chan_ok ;
bool connecting ;
bool connected ; /* true = the channel is connected to the guest */
bool heartbeating ; /* true = the heartbeating has started */
string name_log_prefix ;
string uuid_log_prefix ;
int connect_wait_in_secs ;
/* added service bools */
service_type heartbeat ;
service_type reserved ;
/*
* File and watch descriptors used to monitor
* specific files in QEMU_CHANNEL_DIR
*/
int inotify_file_fd ;
int inotify_file_wd ;
/* Message header info */
int version;
int revision;
string msg_type;
uint32_t sequence;
hb_state_t hbState ; /* see heartbeat_types.h */
hb_state_t vnState ; /* see heartbeat_types.h */
uint32_t invocation_id ;
// For voting and notification
string event_type; // GuestHeartbeatMsgEventT
string notification_type; // GuestHeartbeatMsgNotifyT
uint32_t heartbeat_challenge ;
uint32_t heartbeat_interval_ms ;
uint32_t vote_secs;
uint32_t shutdown_notice_secs;
uint32_t suspend_notice_secs;
uint32_t resume_notice_secs;
uint32_t restart_secs;
string corrective_action;
string unhealthy_corrective_action;
bool unhealthy_failure ;
/* String versions of the above timeouts - integer portions only */
string vote_to_str ; /* vote timeout in seconds as a string value */
string shutdown_to_str ; /* shutdown timeout in seconds as a string value */
string suspend_to_str ; /* suspend timeout in seconds as a string value */
string resume_to_str ; /* resume timeout in seconds as a string value */
string restart_to_str ; /* restart timeout in seconds as a string value */
int select_count ;
int message_count ;
int health_count ;
int failure_count ;
int connect_count ;
int connect_retry_count ;
int corrective_action_count ;
libEvent vimEvent ;
} instInfo ;
/* daemon control structure - used for both guestAgent and guestServer */
typedef struct
{
bool init ;
char hostname [MAX_HOST_NAME_SIZE+1];
string address ;
string address_peer ; /* used for server only */
int nodetype ; /* used for server only */
guest_services_socket_type sock ;
struct mtc_timer timer ;
/* List of instances provisioned on this host */
list<instInfo> instance_list ; /* used for server only */
list<instInfo>::iterator instance_list_ptr; /* used for server only */
/* file and watch descriptors used to monitor QEMU_CHANNEL_DIR */
int inotify_dir_fd ;
int inotify_dir_wd ;
} ctrl_type ;
ctrl_type * get_ctrl_ptr ( void );
int send_cmd_to_guestServer ( string hostname, unsigned int cmd, string uuid, bool reporting, string event="unknown" );
/**
* @} guest_services_base
*/
#endif /* __INCLUDE_GUESTBASE_H__ */

File diff suppressed because it is too large Load Diff

View File

@ -1,202 +0,0 @@
#ifndef __INCLUDE_GUESTCLASS_H__
#define __INCLUDE_GUESTCLASS_H__
/*
* Copyright (c) 2015 Wind River Systems, Inc.
*
* SPDX-License-Identifier: Apache-2.0
*
*/
#include "guestBase.h"
#include "httpUtil.h" /* for ... libEvent and httpUtil_... */
#include "hostClass.h"
typedef enum
{
STAGE__START,
STAGES
} guest_stage_enum ;
class guestHostClass
{
private:
struct guest_host {
/** Pointer to the previous / next host in the list */
struct guest_host * prev;
struct guest_host * next;
string hostname ;
string uuid ;
string ip ;
int hosttype ;
/**
* Top level gate for the host.
* If false then reporting for all instances are off.
*/
bool reporting;
bool query_flag ;
int query_misses ;
/** Instance level Audit timer */
struct mtc_timer host_audit_timer;
/** flag that indicates we were able to fetch host state from the VIM */
bool got_host_state ;
/** flag that indicates we were able to fetch intances from the VIM */
bool got_instances ;
/** Main FSM stage */
guest_stage_enum stage ;
/* List of instances for this host */
list<instInfo> instance_list ;
list<instInfo>::iterator instance_list_ptr;
libEvent vimEvent ;
};
/** List of allocated host memory.
*
* An array of host pointers.
*/
guest_host * host_ptrs[MAX_HOSTS] ;
/** A memory allocation counter.
*
* Should represent the number of hosts in the linked list.
*/
int memory_allocs ;
/** A memory used counter
*
* A variable storing the accumulated host memory
*/
int memory_used ;
// struct hostBaseClass::host* getHost ( string hostname );
struct guest_host * guest_head ; /**< Host Linked List Head pointer */
struct guest_host * guest_tail ; /**< Host Linked List Tail pointer */
struct guestHostClass::guest_host* newHost ( void );
struct guestHostClass::guest_host* addHost ( string hostname );
struct guestHostClass::guest_host* getHost ( string hostname );
int remHost ( string hostname );
int delHost ( struct guestHostClass::guest_host * guest_host_ptr );
struct guestHostClass::guest_host* getHost_timer ( timer_t tid );
libEvent & getEvent ( struct event_base * base_ptr, string & hostname );
const
char * get_guestStage_str ( struct guestHostClass::guest_host * guest_host_ptr );
int guestStage_change ( struct guestHostClass::guest_host * guest_host_ptr, guest_stage_enum newStage );
void mem_log_info ( void );
void mem_log_info_host ( struct guestHostClass::guest_host * guest_host_ptr );
void mem_log_info_inst ( struct guestHostClass::guest_host * guest_host_ptr );
public:
guestHostClass(); /**< constructor */
~guestHostClass(); /**< destructor */
hostBaseClass hostBase ;
bool exit_fsm ;
void run_fsm ( string hostname );
bool audit_run ;
/** Host level Audit timer */
struct mtc_timer audit_timer;
/** This is a list of host names. */
std::list<string> hostlist ;
std::list<string>::iterator hostlist_iter_ptr ;
// void guest_fsm ( void );
int hosts ;
/* For select dispatch */
struct timeval waitd ;
fd_set inotify_readfds ;
fd_set instance_readfds ;
fd_set message_readfds ;
int add_host ( string uuid, string address, string hostname, string nodetype );
int mod_host ( string uuid, string address, string hostname, string nodetype );
int del_host ( string hostname ); /* delete the host from the daemon - mtcAgent */
int rem_host ( string hostname );
/** Delete all instances for this host */
int del_host_inst ( string host_uuid );
int add_inst ( string hostname, instInfo & instance );
int mod_inst ( string hostname, instInfo & instance );
int del_inst ( string instance );
instInfo * get_inst ( string instance );
/* The handler that lib event calls to handle the return response */
void guestVimApi_handler ( struct evhttp_request *req, void *arg );
/**
* Change all the instance service states to enabled or disable
* for the specified host.
**/
int host_inst( string hostname , mtc_cmd_enum command );
/**
* Set and Get a bool that indicates whether we already
* got the host reporting state from the VIM.
*
* The VIM might not be running at the time this daemon
* is started so we need to retry until we get it
**/
void set_got_host_state ( string hostname );
bool get_got_host_state ( string hostname );
void set_got_instances ( string hostname );
bool get_got_instances ( string hostname );
/** returns he number of instances on this host */
int num_instances ( string hostname );
string get_host_name ( string host_uuid );
string get_host_uuid ( string hostname );
string get_host_ip ( string hostname );
string get_inst_host_name ( string instance_uuid );
/* Send the instance reporting state to the guestServer on that host
* primarily used to preiodically refresh instance reporting state or
* set it when the guestServer seems to have restarted */
int set_inst_state ( string hostname );
libEvent & get_host_event ( string hostname );
void inc_query_misses ( string hostname );
void clr_query_misses ( string hostname );
int get_query_misses ( string hostname );
void set_query_flag ( string hostname );
void clr_query_flag ( string hostname );
bool get_query_flag ( string hostname );
bool get_reporting_state( string hostname );
int set_reporting_state( string hostname, bool enabled );
void memLogDelimit ( void ); /**< Debug log delimiter */
void memDumpNodeState ( string hostname );
void memDumpAllState ( void );
void print_node_info ( void ); /**< Print node info banner */
};
guestHostClass * get_hostInv_ptr ( void );
#endif /* __INCLUDE_GUESTCLASS_H__ */

File diff suppressed because it is too large Load Diff

View File

@ -1,27 +0,0 @@
/*
* Copyright (c) 2013, 2015 Wind River Systems, Inc.
*
* SPDX-License-Identifier: Apache-2.0
*
*/
/**
* @file
* Wind River CGTS Platform Controller Maintenance Daemon
*/
typedef struct
{
struct sockaddr_in addr ;
struct event_base * base ;
struct evhttp_request * req ;
struct evhttp * httpd ;
int fd ;
int port ;
} request_type ;
void guestHttpSvr_fini ( void );
int guestHttpSvr_init ( int port );
int guestHttpSvr_setup ( request_type & request );
void guestHttpSvr_look ( void );

View File

@ -1,227 +0,0 @@
/*
* Copyright (c) 2013, 2015 Wind River Systems, Inc.
*
* SPDX-License-Identifier: Apache-2.0
*
*/
/**
* @file
* Wind River CGTS Platform Controller Maintenance HTTP Utilities.
*
* Public Interfaces:
*
*/
#include <iostream>
#include <evhttp.h>
#include <list>
using namespace std;
#include "httpUtil.h" /* for ... common http utilities */
#include "jsonUtil.h" /* for ... Json Utilities */
#include "nodeUtil.h" /* for ... Node Utilities */
#include "guestClass.h" /* for ... maintenance class nodeLinkClass */
#include "guestHttpUtil.h" /* for ... this module header */
#include "guestVimApi.h" /* for ... guestVimApi_Handler */
/* Module init */
void guestHttpUtil_init ( void )
{
return ;
}
/* Module close */
void guestHttpUtil_fini ( void )
{
return ;
}
/* *********************************************************************
*
* Name : guestHttpUtil_status
*
* Description: Extracts and returns the HTTP execution status
*
* *********************************************************************/
int guestHttpUtil_status ( libEvent & event )
{
int rc = PASS ;
if ( !event.req )
{
elog ("%s Invalid request\n", event.hostname.length() ? event.hostname.c_str() : "unknown" );
return (FAIL_UNKNOWN_HOSTNAME);
}
event.status = event.http_status = evhttp_request_get_response_code (event.req);
switch (event.status)
{
case HTTP_OK:
case 201:
case 202:
case 203:
case 204:
{
dlog ("%s HTTP_OK (%d)\n", event.hostname.c_str(), event.status );
event.status = PASS ;
break;
}
/* Authentication error - refresh the token */
case 401:
{
rc = FAIL_AUTHENTICATION ;
break ;
}
case 0:
{
wlog ("%s Status:0 - failed to connect to '%s:%d'\n",
event.hostname.c_str(), event.ip.c_str(), event.port);
event.status = FAIL_HTTP_ZERO_STATUS ;
rc = FAIL_HTTP_ZERO_STATUS ;
break ;
}
default:
{
dlog3 ("%s Status: %d\n", event.hostname.c_str(), event.status );
rc = event.status ;
break;
}
}
return (rc);
}
/* ***********************************************************************
*
* Name : guestHttpUtil_api_req
*
* Description: Makes an HTTP request based on all the info
* in the supplied libEvent.
*
* ************************************************************************/
int guestHttpUtil_api_req ( libEvent & event )
{
http_headers_type hdrs ;
bool has_payload = false;
int hdr_entry = 0 ;
int rc = FAIL ;
void(*handler)(struct evhttp_request *, void *) = NULL ;
/* Bind the unlock handler */
handler = &guestVimApi_Handler;
/* set the timeout */
event.timeout = HTTP_VIM_TIMEOUT ;
/* Check for memory leaks */
if ( event.base )
{
slog ("%s http base memory leak avoidance (%p) fixme !!\n",
event.log_prefix.c_str(), event.base );
// event_base_free(event.base);
}
/* Allocate the base */
event.base = event_base_new();
if ( event.base == NULL )
{
elog ("%s No Memory for Request\n", event.log_prefix.c_str());
return ( FAIL_EVENT_BASE );
}
/* Establish connection */
else if ( httpUtil_connect ( event ))
{
return (FAIL_CONNECT);
}
else if ( httpUtil_request ( event, handler ))
{
return (FAIL_REQUEST_NEW);
}
jlog ("%s Address : %s\n", event.hostname.c_str(), event.token.url.c_str());
if ((( event.type != EVHTTP_REQ_GET ) && ( event.type != EVHTTP_REQ_DELETE )) ||
( event.request == VIM_HOST_STATE_QUERY ))
{
has_payload = true ;
/* Add payload to the output buffer but only for PUT, POST and PATCH requests */
if ( httpUtil_payload_add ( event ))
{
return (FAIL_PAYLOAD_ADD);
}
jlog ("%s Payload : %s\n", event.hostname.c_str(),
event.payload.c_str() );
}
/* Convert port to a string */
char port_str[10] ;
sprintf ( port_str, "%d", event.port );
/* Build the HTTP Header */
hdrs.entry[hdr_entry].key = "Host" ;
hdrs.entry[hdr_entry].value = event.ip ;
hdrs.entry[hdr_entry].value.append(":") ;
hdrs.entry[hdr_entry].value.append(port_str);
hdr_entry++;
if ( has_payload == true )
{
hdrs.entry[hdr_entry].key = "Content-Length" ;
hdrs.entry[hdr_entry].value = httpUtil_payload_len ( &event );
hdr_entry++;
}
hdrs.entry[hdr_entry].key = "User-Agent" ;
hdrs.entry[hdr_entry].value = "guest-agent/1.0" ;
hdr_entry++;
hdrs.entry[hdr_entry].key = "Content-Type" ;
hdrs.entry[hdr_entry].value = "application/json" ;
hdr_entry++;
hdrs.entry[hdr_entry].key = "Connection" ;
hdrs.entry[hdr_entry].value = "close" ;
hdr_entry++;
hdrs.entries = hdr_entry ;
/* Add the headers */
if ( httpUtil_header_add ( &event, &hdrs ))
{
return (FAIL_HEADER_ADD);
}
event.address = event.token.url ;
rc = evhttp_make_request ( event.conn, event.req, event.type, event.token.url.data());
if ( rc == PASS )
{
evhttp_connection_set_timeout(event.req->evcon, event.timeout);
/* Default to retry for both blocking and non-blocking command */
event.status = RETRY ;
event.log_prefix = event.hostname ;
event.log_prefix.append (" ");
event.log_prefix.append (event.service) ;
event.log_prefix.append (" ");
event.log_prefix.append (event.operation) ;
jlog2 ("%s Requested (blocking) (to:%d)\n", event.log_prefix.c_str(), event.timeout);
/* Send the message with timeout */
event_base_dispatch(event.base);
httpUtil_free_conn ( event );
httpUtil_free_base ( event );
return(event.status) ;
}
elog ("%s Call to 'evhttp_make_request' failed (rc:%d)\n",
event.hostname.c_str(), rc);
return (FAIL_MAKE_REQUEST);
}

View File

@ -1,32 +0,0 @@
#ifndef __INCLUDE_GUESTHTTPUTIL_H__
#define __INCLUDE_GUESTHTTPUTIL_H__
/*
* Copyright (c) 2013, 2015 Wind River Systems, Inc.
*
* SPDX-License-Identifier: Apache-2.0
*
*/
/**
* @file
* Wind River CGTS Platform Controller Maintenance ...
*
* libevent HTTP support utilities and control structure support header
*/
#include <iostream> /* for ... string */
#include <evhttp.h> /* for ... http libevent client */
using namespace std;
#include "guestClass.h" /* for ... maintenance class nodeLinkClass */
#include "httpUtil.h" /* for ... common http utilities */
/***********************************************************************/
void guestHttpUtil_init ( void );
void guestHttpUtil_fini ( void );
int guestHttpUtil_status ( libEvent & event );
int guestHttpUtil_api_req ( libEvent & event );
#endif /* __INCLUDE_GUESTHTTPUTIL_H__ */

View File

@ -1,764 +0,0 @@
/*
* Copyright (c) 2013-2016 Wind River Systems, Inc.
*
* SPDX-License-Identifier: Apache-2.0
*
*/
/**
* @file
* Wind River CGTS Platform Guest Services "Instances Base Class"
*/
#include <sys/types.h>
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
using namespace std;
#include "nodeBase.h" /* for ... common definitions */
#include "nodeEvent.h" /* for ... set_inotify_watch_file */
#include "nodeTimers.h" /* for ... mtcTimer */
#include "guestBase.h" /* for ... instInfo */
#include "guestUtil.h" /* for ... guestUtil_inst_init */
#include "guestInstClass.h" /* for ... get_inst */
#include "guestSvrUtil.h" /* for ... hb_get_state_name */
/**< constructor */
guestInstClass::guestInstClass()
{
inst_head = NULL ;
inst_tail = NULL ;
memory_allocs = 0 ;
memory_used = 0 ;
instances = 0 ;
for ( int i = 0 ; i < MAX_INSTANCES ; i++ )
{
inst_ptrs[i] = NULL ;
}
fsm_exit = false ;
reporting = true ;
return ;
}
/**< destructor */
guestInstClass::~guestInstClass()
{
inst * inst_ptr = inst_head ;
inst * temp_ptr = inst_ptr ;
while ( inst_ptr != NULL )
{
temp_ptr = inst_ptr ;
inst_ptr = inst_ptr->next ;
delInst (temp_ptr);
}
if ( memory_used != 0 )
{
elog ( "Apparent Memory Leak - Allocs:%d and Bytes:%d\n",
memory_allocs, memory_used );
}
else
{
dlog ( "No Memory Leaks\n\n");
}
return ;
}
void guestInstClass::guest_fsm_run ( void )
{
fsm_run ();
}
/*
* Allocate new instance and tack it on the end of the instance list
*/
struct guestInstClass::inst* guestInstClass::addInst ( string uuid )
{
if ( uuid.length() != UUID_LEN )
{
elog ("invalid instance uuid ; cannot add %s\n", uuid.c_str());
return static_cast<struct inst *>(NULL);
}
/* verify instance is not already provisioned */
struct inst * inst_ptr = guestInstClass::getInst ( uuid );
if ( inst_ptr )
{
if ( guestInstClass::remInst ( uuid ) )
{
/* Should never get here but if we do then */
/* something is seriously wrong */
elog ("%s unable to remove instance during reprovision\n",
log_prefix(&inst_ptr->instance).c_str());
return static_cast<struct inst *>(NULL);
}
}
/* allocate memory for new instance */
inst_ptr = guestInstClass::newInst ();
if( inst_ptr == NULL )
{
elog ( "failed to allocate memory for new instance\n" );
return static_cast<struct inst *>(NULL);
}
guestUtil_inst_init ( &inst_ptr->instance );
/* Init the new instance */
inst_ptr->instance.uuid = uuid ;
inst_ptr->query_flag = false ;
inst_ptr->instance.connect_wait_in_secs = DEFAULT_CONNECT_WAIT ;
/* Init instance's connect and monitor timers */
/* Assign the timer the instance's name */
mtcTimer_init ( inst_ptr->reconnect_timer, uuid );
mtcTimer_init ( inst_ptr->connect_timer, uuid );
mtcTimer_init ( inst_ptr->monitor_timer, uuid );
mtcTimer_init ( inst_ptr->init_timer, uuid );
mtcTimer_init ( inst_ptr->vote_timer, uuid );
inst_ptr->action = FSM_ACTION__NONE ;
inst_ptr->connectStage = INST_CONNECT__START ;
inst_ptr->monitorStage = INST_MONITOR__STEADY ;
inst_ptr->messageStage = INST_MESSAGE__RECEIVE ;
/* If the instance list is empty add it to the head */
if( inst_head == NULL )
{
inst_head = inst_ptr ;
inst_tail = inst_ptr ;
inst_ptr->prev = NULL ;
inst_ptr->next = NULL ;
}
else
{
/* link the new_instance to the tail of the inst_list
* then mark the next field as the end of the inst_list
* adjust tail to point to the last instance
*/
inst_tail->next = inst_ptr ;
inst_ptr->prev = inst_tail ;
inst_ptr->next = NULL ;
inst_tail = inst_ptr ;
}
instances++ ;
ilog ("%s added as instance %d\n", log_prefix(&inst_ptr->instance).c_str(), instances);
return inst_ptr ;
}
/* Remove an instance from the linked list of instances - may require splice action */
int guestInstClass::remInst( string uuid )
{
if ( uuid.empty() )
return -ENODEV ;
if ( inst_head == NULL )
return -ENXIO ;
struct inst * inst_ptr = getInst ( uuid );
if ( inst_ptr == NULL )
return -EFAULT ;
stop_instance_timers ( inst_ptr );
/* Close the channel if it is open */
guestUtil_close_channel ( &inst_ptr->instance );
/* If the instance is the head instance */
if ( inst_ptr == inst_head )
{
/* only one instance in the list case */
if ( inst_head == inst_tail )
{
dlog2 ("Single Inst -> Head Case\n");
inst_head = NULL ;
inst_tail = NULL ;
}
else
{
dlog2 ("Multiple Insts -> Head Case\n");
inst_head = inst_head->next ;
inst_head->prev = NULL ;
}
}
/* if not head but tail then there must be more than one
* instance in the list so go ahead and chop the tail.
*/
else if ( inst_ptr == inst_tail )
{
dlog2 ("Multiple Inst -> Tail Case\n");
inst_tail = inst_tail->prev ;
inst_tail->next = NULL ;
}
else
{
dlog2 ("Multiple Inst -> Full Splice Out\n");
inst_ptr->prev->next = inst_ptr->next ;
inst_ptr->next->prev = inst_ptr->prev ;
}
delInst ( inst_ptr );
instances-- ;
if ( instances == 0 )
ilog ("no instances to monitor\n");
return (PASS) ;
}
/* Perform a linked list search for the instance matching the instance name */
struct guestInstClass::inst* guestInstClass::getInst ( string chan_or_uuid )
{
struct inst * inst_ptr = static_cast<struct inst *>(NULL) ;
/* check for empty list condition */
if ( inst_head )
{
for ( inst_ptr = inst_head ; inst_ptr != NULL ; inst_ptr = inst_ptr->next )
{
if ( !inst_ptr->instance.uuid.compare (chan_or_uuid) )
{
return inst_ptr ;
}
if ( !inst_ptr->instance.chan.compare (chan_or_uuid) )
{
return inst_ptr ;
}
if (( inst_ptr->next == NULL ) || ( inst_ptr == inst_tail ))
break ;
}
}
return static_cast<struct inst *>(NULL);
}
/*
* Allocates memory for a new instance and stores its address in inst_ptrs
*
* @param void
* @return pointer to the newly allocted instance memory
*/
struct guestInstClass::inst * guestInstClass::newInst ( void )
{
struct guestInstClass::inst * temp_inst_ptr = NULL ;
if ( memory_allocs == 0 )
{
memset ( inst_ptrs, 0 , sizeof(struct inst *)*MAX_INSTANCES);
}
// find an empty spot
for ( int i = 0 ; i < MAX_INSTANCES ; i++ )
{
if ( inst_ptrs[i] == NULL )
{
inst_ptrs[i] = temp_inst_ptr = new inst ;
memory_allocs++ ;
memory_used += sizeof (struct guestInstClass::inst);
return temp_inst_ptr ;
}
}
elog ( "failed to store new instance pointer address\n" );
return temp_inst_ptr ;
}
/* Frees the memory of a pre-allocated instance and removes
* it from the inst_ptrs list.
*
* @param instance * pointer to the instance memory address to be freed
* @return int return code { PASS or -EINVAL }
*/
int guestInstClass::delInst ( struct guestInstClass::inst * inst_ptr )
{
if ( memory_allocs > 0 )
{
for ( int i = 0 ; i < MAX_INSTANCES ; i++ )
{
if ( inst_ptrs[i] == inst_ptr )
{
delete inst_ptr ;
inst_ptrs[i] = NULL ;
memory_allocs-- ;
memory_used -= sizeof (struct guestInstClass::inst);
return PASS ;
}
}
elog ( "unable to validate memory address being freed\n" );