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

Depends-On: https://review.openstack.org/603435

Change-Id: I2ebaf07b94ee5b5abdf8f8db80536351ded22078
Signed-off-by: Jim Gauld <james.gauld@windriver.com>
changes/43/603443/3
Jim Gauld 5 years ago
parent 2d39affda2
commit d2b3e22a4e

@ -18,3 +18,7 @@ nfv-plugins
nfv-tools
nfv-vim
nfv-client
# mtce-guest
mtce-guestAgent
mtce-guestServer

@ -3,3 +3,4 @@ guest-client
guest-agent
guest-comm
nfv
mtce-guest

@ -0,0 +1,13 @@
Metadata-Version: 1.1
Name: mtce-guest
Version: 1.0
Summary: Maintenance Guest Server/Agent Package
Home-page:
Author: Windriver
Author-email: info@windriver.com
License: Apache-2.0
Description: Maintenance Guest Server/Agent package containing daemons, resource and
file system daemons, as well as support files for each.
Platform: UNKNOWN

@ -0,0 +1,3 @@
SRC_DIR="src"
TIS_PATCH_VER=139
BUILD_IS_SLOW=5

@ -0,0 +1,222 @@
Summary: Maintenance Guest Server/Agent Package
Name: mtce-guest
Version: 1.0
%define patchlevel %{tis_patch_ver}
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: openssl
BuildRequires: openssl-devel
BuildRequires: json-c
BuildRequires: json-c-devel
BuildRequires: libevent
BuildRequires: libevent-devel
BuildRequires: libuuid
BuildRequires: libuuid-devel
BuildRequires: fm-common
BuildRequires: fm-common-dev
BuildRequires: guest-client-devel
BuildRequires: mtce-common-dev >= 1.0
BuildRequires: systemd-devel
BuildRequires: cppcheck
%description
Maintenance Guest Agent Service and Server assists in VM guest
heartbeat control and failure reporting at the controller level.
%package -n mtce-guestAgent
Summary: Maintenance Guest Agent Package
Group: base
Requires: dpkg
Requires: time
Requires: libjson-c.so.2()(64bit)
Requires: libstdc++.so.6(CXXABI_1.3)(64bit)
Requires: librt.so.1(GLIBC_2.2.5)(64bit)
Requires: libfmcommon.so.1()(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: 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: libevent >= 2.0.21
Requires: libevent-2.0.so.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()(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)
%description -n mtce-guestAgent
Maintenance Guest Agent Service assists in
VM guest heartbeat control and failure reporting at the controller
level.
%package -n mtce-guestServer
Summary: Maintenance Guest Server Package
Group: base
Requires: util-linux
Requires: /bin/bash
Requires: /bin/systemctl
Requires: dpkg
Requires: libjson-c.so.2()(64bit)
Requires: libstdc++.so.6(CXXABI_1.3)(64bit)
Requires: librt.so.1(GLIBC_2.2.5)(64bit)
Requires: libfmcommon.so.1()(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: 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: libevent >= 2.0.21
Requires: libevent-2.0.so.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: 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)
%description -n mtce-guestServer
Maintenance Guest Server assists in VM guest
heartbeat control and failure reporting at the compute level.
%define local_dir /usr/local
%define local_bindir %{local_dir}/bin
%define local_sbindir %{local_dir}/sbin
%define local_etc_pmond %{_sysconfdir}/pmon.d
%define local_etc_servicesd %{_sysconfdir}/services.d
%define local_etc_logrotated %{_sysconfdir}/logrotate.d
%define ocf_resourced /usr/lib/ocf/resource.d
%prep
%setup
# build mtce-guestAgent and mtce-guestServer package
%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 mtce-guestAgent and mtce-guestServer package
%install
VER=%{version}
MAJOR=$(echo $VER | awk -F . '{print $1}')
MINOR=$(echo $VER | awk -F . '{print $2}')
install -m 755 -d %{buildroot}%{_sysconfdir}
install -m 755 -d %{buildroot}/usr
install -m 755 -d %{buildroot}/%{_bindir}
install -m 755 -d %{buildroot}/usr/local
install -m 755 -d %{buildroot}%{local_bindir}
install -m 755 -d %{buildroot}/usr/local/sbin
install -m 755 -d %{buildroot}/%{_sbindir}
install -m 755 -d %{buildroot}/lib
install -m 755 -d %{buildroot}%{_sysconfdir}/mtc
install -m 755 -d %{buildroot}%{_sysconfdir}/mtc/tmp
# resource agent stuff
install -m 755 -d %{buildroot}/usr/lib
install -m 755 -d %{buildroot}/usr/lib/ocf
install -m 755 -d %{buildroot}/usr/lib/ocf/resource.d
install -m 755 -d %{buildroot}/usr/lib/ocf/resource.d/platform
install -m 755 -p -D %{_buildsubdir}/scripts/guestAgent.ocf %{buildroot}/usr/lib/ocf/resource.d/platform/guestAgent
# config files
install -m 644 -p -D %{_buildsubdir}/scripts/guest.ini %{buildroot}%{_sysconfdir}/mtc/guestAgent.ini
install -m 644 -p -D %{_buildsubdir}/scripts/guest.ini %{buildroot}%{_sysconfdir}/mtc/guestServer.ini
# binaries
install -m 755 -p -D %{_buildsubdir}/guestServer %{buildroot}/%{local_bindir}/guestServer
install -m 755 -p -D %{_buildsubdir}/guestAgent %{buildroot}/%{local_bindir}/guestAgent
# init script files
install -m 755 -p -D %{_buildsubdir}/scripts/guestServer %{buildroot}%{_sysconfdir}/init.d/guestServer
install -m 755 -p -D %{_buildsubdir}/scripts/guestAgent %{buildroot}%{_sysconfdir}/init.d/guestAgent
# systemd service files
install -m 644 -p -D %{_buildsubdir}/scripts/guestServer.service %{buildroot}%{_unitdir}/guestServer.service
install -m 644 -p -D %{_buildsubdir}/scripts/guestAgent.service %{buildroot}%{_unitdir}/guestAgent.service
# process monitor config files
install -m 755 -d %{buildroot}%{local_etc_pmond}
install -m 644 -p -D %{_buildsubdir}/scripts/guestServer.pmon %{buildroot}%{local_etc_pmond}/guestServer.conf
# log rotation
install -m 755 -d %{buildroot}%{_sysconfdir}/logrotate.d
install -m 644 -p -D %{_buildsubdir}/scripts/guestAgent.logrotate %{buildroot}%{local_etc_logrotated}/guestAgent.logrotate
install -m 644 -p -D %{_buildsubdir}/scripts/guestServer.logrotate %{buildroot}%{local_etc_logrotated}/guestServer.logrotate
# volatile directores
install -m 755 -d %{buildroot}/var
install -m 755 -d %{buildroot}/var/run
# enable all services in systemd
%post -n mtce-guestServer
/bin/systemctl enable guestServer.service
%files -n mtce-guestAgent
%license LICENSE
%defattr(-,root,root,-)
# create mtc and its tmp dir
%dir %{_sysconfdir}/mtc
%dir %{_sysconfdir}/mtc/tmp
# config files - non-modifiable
%{_sysconfdir}/mtc/guestAgent.ini
%{_unitdir}/guestAgent.service
%{local_etc_logrotated}/guestAgent.logrotate
%{ocf_resourced}/platform/guestAgent
%{_sysconfdir}/init.d/guestAgent
%{local_bindir}/guestAgent
%files -n mtce-guestServer
%license LICENSE
%defattr(-,root,root,-)
# create mtc and its tmp dir
%dir %{_sysconfdir}/mtc
%dir %{_sysconfdir}/mtc/tmp
# config files - non-modifiable
%{_sysconfdir}/mtc/guestServer.ini
%{local_etc_pmond}/guestServer.conf
%{local_etc_logrotated}/guestServer.logrotate
%{_unitdir}/guestServer.service
%{_sysconfdir}/init.d/guestServer
%{local_bindir}/guestServer

@ -0,0 +1,202 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

@ -0,0 +1,36 @@
#
# 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. -I/usr/include/mtce-common -I/usr/include/mtce-daemon
build: $(OBJS)
$(CXX) $(CCPFLAGS) $(AGENT_OBJS) $(LDLIBS) -L. -o guestAgent
$(CXX) $(CCPFLAGS) $(SERVER_OBJS) $(LDLIBS) -L. -o guestServer
.cpp.o:
$(CXX) $(INCLUDES) $(CCPFLAGS) $(EXTRACCFLAGS) -c $< -o $@
clean:
@rm -v -f $(OBJ) guestAgent guestServer *.o *.a

@ -0,0 +1,67 @@
This maintenance common guest service provides a means of guest heartbeat
orchestration under VIM (system management) control.
1. Packaging and Initialization:
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.
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
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.

File diff suppressed because it is too large Load Diff

@ -0,0 +1,319 @@
#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

@ -0,0 +1,202 @@
#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

@ -0,0 +1,27 @@
/*
* 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 );

@ -0,0 +1,227 @@
/*
* 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);
}

@ -0,0 +1,32 @@
#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__ */

@ -0,0 +1,764 @@
/*
* 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 ;
}
}