StarlingX open source release updates
Signed-off-by: Dean Troyer <dtroyer@gmail.com>
This commit is contained in:
1 parent
05c408a5cd
commit
85cd488bef
714 files changed
+172490
No files matched your search
@@ -0,0 +1,10 @@
|
||||
The following contributors from Wind River have developed the seed code in this
|
||||
repository. We look forward to community collaboration and contributions for
|
||||
additional features, enhancements and refactoring.
|
||||
|
||||
Contributors:
|
||||
=============
|
||||
Bart Wensley <Barton.Wensley@windriver.com>
|
||||
Tao Liu <Tao.Liu@windriver.com>
|
||||
Eric Macdonald <Eric.MacDonald@windriver.com>
|
||||
Jack Ding <Jack.Ding@windriver.com>
|
||||
@@ -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,5 @@
|
||||
=======
|
||||
stx-nfv
|
||||
=======
|
||||
|
||||
StarlingX NFVI Orchestration
|
||||
@@ -0,0 +1,12 @@
|
||||
Metadata-Version: 1.1
|
||||
Name: guest-scale-agent
|
||||
Version: 2.0
|
||||
Summary: Titanium Cloud agent and helper app to scale VMs up/down
|
||||
Home-page:
|
||||
Author: Windriver
|
||||
Author-email: info@windriver.com
|
||||
License: Apache-2.0
|
||||
|
||||
Description: Titanium Cloud agent and helper app to scale VMs up/down
|
||||
|
||||
Platform: UNKNOWN
|
||||
@@ -0,0 +1,2 @@
|
||||
SRC_DIR="guest-scale-agent-2.0"
|
||||
TIS_PATCH_VER=6
|
||||
@@ -0,0 +1,137 @@
|
||||
Summary: Titanium Cloud agent and helper app to scale VMs up/down
|
||||
Name: guest-scale-agent
|
||||
Version: 2.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
|
||||
|
||||
%define cgcs_sdk_deploy_dir /opt/deploy/cgcs_sdk
|
||||
Source0: %{name}-%{version}.tar.gz
|
||||
|
||||
BuildRequires: json-c-devel
|
||||
BuildRequires: host-guest-comm-dev
|
||||
BuildRequires: guest-host-comm-dev
|
||||
BuildRequires: systemd-devel
|
||||
|
||||
Requires: bash
|
||||
|
||||
%description
|
||||
Titanium Cloud agent and helper app to scale VMs up/down
|
||||
|
||||
%package -n guest-scale-agent-dbg
|
||||
Summary: Titanium Cloud agent and helper app to scale VMs up/down - Debugging files
|
||||
Group: devel
|
||||
|
||||
%description -n guest-scale-agent-dbg
|
||||
Titanium Cloud agent and helper app to scale VMs up/down This package contains ELF
|
||||
symbols and related sources for debugging purposes.
|
||||
|
||||
%package -n guest-scale-agent-dev
|
||||
Summary: Titanium Cloud agent and helper app to scale VMs up/down - Development files
|
||||
Group: devel
|
||||
Requires: guest-scale-agent = %{version}-%{release}
|
||||
|
||||
%description -n guest-scale-agent-dev
|
||||
Titanium Cloud agent and helper app to scale VMs up/down This package contains
|
||||
symbolic links, header files, and related items necessary for software
|
||||
development.
|
||||
|
||||
%package -n guest-scale-helper
|
||||
Summary: Titanium Cloud agent and helper app to scale VMs up/down
|
||||
Group: base
|
||||
Requires: rtld(GNU_HASH)
|
||||
|
||||
%description -n guest-scale-helper
|
||||
Titanium Cloud agent and helper app to scale VMs up/down
|
||||
|
||||
%package -n %{name}-cgts-sdk
|
||||
Summary: SDK files for Titanium Cloud agent and helper app to scale VMs up/down
|
||||
Group: devel
|
||||
|
||||
%description -n %{name}-cgts-sdk
|
||||
SDK files for Titanium Cloud agent and helper app to scale VMs up/down
|
||||
%prep
|
||||
%setup
|
||||
|
||||
|
||||
%build
|
||||
VER=%{version}
|
||||
MAJOR=`echo $VER | awk -F . '{print $1}'`
|
||||
MINOR=`echo $VER | awk -F . '{print $2}'`
|
||||
PATCH=%{patchlevel}
|
||||
make all VER=${VER} MAJOR=${MAJOR} MINOR=${MINOR} PATCH=${PATCH}
|
||||
|
||||
%global _buildsubdir %{_builddir}/%{name}-%{version}
|
||||
|
||||
%install
|
||||
install -d 750 -d %{buildroot}/usr/sbin
|
||||
install -d 750 -d %{buildroot}%{_sysconfdir}/init.d
|
||||
|
||||
install -m 750 -d %{buildroot}/usr
|
||||
install -m 750 -d %{buildroot}/usr/src
|
||||
install -m 750 -d %{buildroot}/usr/src/debug
|
||||
install -m 750 -d %{buildroot}/usr/src/debug/%{name}-%{version}
|
||||
install -d 750 -d %{buildroot}/usr/sbin/.debug
|
||||
|
||||
install -m 750 %{_buildsubdir}/scripts/app_scale_helper %{buildroot}/usr/sbin/app_scale_helper
|
||||
install -m 750 %{_buildsubdir}/scripts/offline_cpus %{buildroot}/usr/sbin/offline_cpus
|
||||
install -m 750 %{_buildsubdir}/bin/guest_scale_helper %{buildroot}/usr/sbin/guest_scale_helper
|
||||
install -m 750 %{_buildsubdir}/bin/guest_scale_agent %{buildroot}/usr/sbin/guest_scale_agent
|
||||
install -m 750 %{_buildsubdir}/scripts/init_offline_cpus %{buildroot}/etc/init.d/offline_cpus
|
||||
install -m 750 %{_buildsubdir}/bin/guest_scale_agent %{buildroot}/usr/sbin/.debug/guest_scale_agent
|
||||
|
||||
install -d %{buildroot}%{_unitdir}
|
||||
install -m 750 %{_buildsubdir}/scripts/offline-cpus.service %{buildroot}%{_unitdir}/offline-cpus.service
|
||||
install -m 750 %{_buildsubdir}/scripts/guest-scale-agent.service %{buildroot}%{_unitdir}/guest-scale-agent.service
|
||||
|
||||
# Deploy to the SDK deployment directory
|
||||
install -d %{buildroot}%{cgcs_sdk_deploy_dir}
|
||||
install -m 644 sdk/wrs-guest-scale-%{version}.%{patchlevel}.tgz %{buildroot}%{cgcs_sdk_deploy_dir}/wrs-guest-scale-%{version}.%{patchlevel}.tgz
|
||||
|
||||
|
||||
%post
|
||||
%systemd_post offline-cpus.service
|
||||
%systemd_post guest-scale-agent.service
|
||||
/usr/bin/systemctl enable offline-cpus.service >/dev/null 2>&1
|
||||
/usr/bin/systemctl enable guest-scale-agent.service >/dev/null 2>&1
|
||||
|
||||
%preun
|
||||
%systemd_preun offline-cpus.service
|
||||
%systemd_preun guest-scale-agent.service
|
||||
|
||||
%postun
|
||||
%systemd_postun guest-scale-agent.service
|
||||
%systemd_postun offline-cpus.service
|
||||
|
||||
%files
|
||||
%defattr(-,root,root,-)
|
||||
|
||||
/usr/sbin/guest_scale_agent
|
||||
/usr/sbin/offline_cpus
|
||||
/usr/sbin/app_scale_helper
|
||||
/etc/init.d/offline_cpus
|
||||
%{_unitdir}/offline-cpus.service
|
||||
%{_unitdir}/guest-scale-agent.service
|
||||
|
||||
%files -n guest-scale-agent-dbg
|
||||
%defattr(-,root,root,-)
|
||||
|
||||
/usr/src/debug/*
|
||||
/usr/sbin/.debug/guest_scale_agent
|
||||
|
||||
%files -n guest-scale-agent-dev
|
||||
%defattr(-,root,root,-)
|
||||
|
||||
/usr/sbin/.debug/guest_scale_agent
|
||||
|
||||
%files -n guest-scale-helper
|
||||
%defattr(-,root,root,-)
|
||||
|
||||
/usr/sbin/guest_scale_helper
|
||||
|
||||
%files -n %{name}-cgts-sdk
|
||||
%{cgcs_sdk_deploy_dir}/wrs-guest-scale-%{version}.%{patchlevel}.tgz
|
||||
|
||||
@@ -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,110 @@
|
||||
#
|
||||
# BSD LICENSE
|
||||
#
|
||||
# Copyright(c) 2013-2016, Wind River Systems, Inc.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in
|
||||
# the documentation and/or other materials provided with the
|
||||
# distribution.
|
||||
# * Neither the name of Wind River Systems nor the names of its
|
||||
# contributors may be used to endorse or promote products derived
|
||||
# from this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
# Note: if you change either Makefile or Makefile.sdk you need to manually
|
||||
# do a "make clean" and then "make".
|
||||
|
||||
EXECS = guest_scale_helper guest_scale_agent
|
||||
|
||||
CFLAGS= -g -Wall
|
||||
ODIR=obj
|
||||
BINDIR=bin
|
||||
|
||||
BINEXECS=$(addprefix $(BINDIR)/, $(EXECS))
|
||||
|
||||
GUEST_SCALE_HELPER_SRCS = guest_scale_helper.c parser.c
|
||||
GUEST_SCALE_HELPER_OBJ := $(patsubst %,$(ODIR)/%,$(GUEST_SCALE_HELPER_SRCS:.c=.o))
|
||||
|
||||
GUEST_SCALE_AGENT_SRCS= guest_scale_agent.c parser.c
|
||||
GUEST_SCALE_AGENT_OBJ := $(patsubst %,$(ODIR)/%,$(GUEST_SCALE_AGENT_SRCS:.c=.o))
|
||||
|
||||
OBJS = $(GUEST_SCALE_OBJ) $(GUEST_SCALE_AGENT_OBJ)
|
||||
DEPS = $(OBJS:.o=.d) sdk/sdk.d
|
||||
-include $(DEPS)
|
||||
|
||||
EXPORT_SDK := wrs-guest-scale-$(MAJOR).$(MINOR).$(PATCH)
|
||||
|
||||
# SYSROOT = $(shell for i in $(LD) ; do echo $$i; done | grep sysroot= | awk -F = '{ print $$2 }'`)
|
||||
SYSROOT = $(shell echo "$(LD)" | sed -n -e 's/^.*sysroot=//p' | awk '{ print $$1 }')
|
||||
LIBSERVERGROUP_VER = $(shell find $(SYSROOT) | grep libservergroup.so. | sed -n -e 's/^.*libservergroup\.so\.//p')
|
||||
|
||||
print-%:
|
||||
@echo $* = $($*)
|
||||
|
||||
printvars:
|
||||
@$(foreach V,$(sort $(.VARIABLES)), $(if $(filter-out environment% default automatic, $(origin $V)),$(warning $V=$($V) ($(value $V)))))
|
||||
|
||||
.PHONY: printvars
|
||||
|
||||
all: host_all
|
||||
host_all: $(BINEXECS) sdk/$(EXPORT_SDK).tgz
|
||||
|
||||
# The dependency tracking for the SDK tarball is rather crude. If any
|
||||
# file changes they're all copied over again. This is quick, so it's
|
||||
# not worth getting fancy.
|
||||
sdk/$(EXPORT_SDK).tgz: printvars
|
||||
@echo "Making SDK"
|
||||
@mkdir -p sdk/$(EXPORT_SDK)
|
||||
@mkdir -p sdk/$(EXPORT_SDK)/bin
|
||||
@mkdir -p sdk/$(EXPORT_SDK)/obj
|
||||
@mkdir -p sdk/$(EXPORT_SDK)/scripts
|
||||
@cp scripts/* sdk/$(EXPORT_SDK)/scripts
|
||||
@echo "MAJOR=$(MAJOR)" > sdk/$(EXPORT_SDK)/Makefile
|
||||
@echo "MINOR=$(MINOR)" >> sdk/$(EXPORT_SDK)/Makefile
|
||||
@echo "PATCH=$(PATCH)" >> sdk/$(EXPORT_SDK)/Makefile
|
||||
@cat Makefile.sdk >> sdk/$(EXPORT_SDK)/Makefile
|
||||
@cat docs/README.txt | sed 's/1\.0\.0/$(MAJOR).$(MINOR).$(PATCH)/' | sed 's/9.9.9/${LIBSERVERGROUP_VER}/' > sdk/$(EXPORT_SDK)/README.txt
|
||||
@cp docs/TiS-Guest-Resource-Scaling.pdf sdk/$(EXPORT_SDK)/TiS-Guest-Resource-Scaling.pdf
|
||||
@cp LICENSE sdk/$(EXPORT_SDK)/LICENSE
|
||||
@cp $(GUEST_SCALE_AGENT_SRCS) sdk/$(EXPORT_SDK)
|
||||
@cp misc.h sdk/$(EXPORT_SDK)
|
||||
@cd sdk && tar czf $(EXPORT_SDK).tgz $(EXPORT_SDK)
|
||||
@echo -n "sdk/$(EXPORT_SDK).tgz: Makefile.sdk docs/README.txt docs/TiS-Guest-Resource-Scaling.pdf " > sdk/sdk.d
|
||||
@echo -n "scripts/init_offline_cpus scripts/offline_cpus scripts/offline-cpus.service" >> sdk/sdk.d
|
||||
@echo -n "scripts/app_scale_helper " >> sdk/sdk.d
|
||||
@echo -n "$(GUEST_SCALE_AGENT_SRCS) " >> sdk/sdk.d
|
||||
@echo "misc.h " >> sdk/sdk.d
|
||||
@echo '*' > sdk/.gitignore
|
||||
|
||||
|
||||
$(ODIR)/%.o: %.c
|
||||
$(CC) -c $(CFLAGS) $(CFLAGS2) -MMD -o $@ $<
|
||||
|
||||
$(BINDIR)/guest_scale_agent: $(GUEST_SCALE_AGENT_OBJ)
|
||||
$(CC) -o $@ $^ $(LDFLAGS) -lguesthostmsg -ljson-c
|
||||
|
||||
$(BINDIR)/guest_scale_helper: $(GUEST_SCALE_HELPER_OBJ)
|
||||
$(CC) -o $@ $^ $(LDFLAGS) -lhostguestmsg -ljson-c
|
||||
|
||||
# Add the host clean as a dependency to the SDK stuff
|
||||
clean: host_clean
|
||||
host_clean:
|
||||
rm -rf sdk
|
||||
@@ -0,0 +1,74 @@
|
||||
#
|
||||
# BSD LICENSE
|
||||
#
|
||||
# Copyright(c) 2013-2016, Wind River Systems, Inc.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in
|
||||
# the documentation and/or other materials provided with the
|
||||
# distribution.
|
||||
# * Neither the name of Wind River Systems nor the names of its
|
||||
# contributors may be used to endorse or promote products derived
|
||||
# from this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
|
||||
.PHONY: all clean
|
||||
|
||||
EXECS= guest_scale_agent
|
||||
|
||||
CFLAGS= -g -Wall
|
||||
|
||||
ODIR=obj
|
||||
BINDIR=bin
|
||||
|
||||
GUEST_SCALE_AGENT_SRCS= guest_scale_agent.c parser.c
|
||||
GUEST_SCALE_AGENT_OBJ := $(patsubst %,$(ODIR)/%,$(GUEST_SCALE_AGENT_SRCS:.c=.o))
|
||||
|
||||
BINEXECS=$(addprefix $(BINDIR)/, $(EXECS))
|
||||
|
||||
OBJS = $(GUEST_SCALE_AGENT_OBJ)
|
||||
|
||||
_DEPS = *.h
|
||||
DEPS = $(patsubst %,$(IDIR)/%,$(_DEPS))
|
||||
DEPS = $(OBJS:.o=.d)
|
||||
-include $(DEPS)
|
||||
|
||||
|
||||
WRS_SERVER_GROUP_DIR ?= $(shell find ../wrs-server-group*[0-9] -maxdepth 0 -type d | sort | tail -n 1)
|
||||
WRS_SERVER_GROUP_INC2 = $(WRS_SERVER_GROUP_DIR)/include
|
||||
WRS_SERVER_GROUP_INC ?= $(shell if [ -d $(WRS_SERVER_GROUP_INC2) ]; then echo "$(WRS_SERVER_GROUP_INC2)"; else echo "/usr/include"; fi)
|
||||
WRS_SERVER_GROUP_LIB2 = $(WRS_SERVER_GROUP_DIR)/lib
|
||||
WRS_SERVER_GROUP_LIB3 = $(shell if [ -d /usr/lib64 ]; then echo "/usr/lib64"; else echo "/usr/lib"; fi)
|
||||
WRS_SERVER_GROUP_LIB ?= $(shell if [ -d $(WRS_SERVER_GROUP_LIB2) ]; then echo "$(WRS_SERVER_GROUP_LIB2)"; else echo "$(WRS_SERVER_GROUP_LIB3)"; fi)
|
||||
|
||||
CFLAGS += -I$(WRS_SERVER_GROUP_INC)
|
||||
LDFLAGS += -L$(WRS_SERVER_GROUP_LIB)
|
||||
|
||||
$(ODIR)/%.o: %.c
|
||||
$(CC) -c $(CFLAGS) $(CFLAGS2) -MMD -o $@ $<
|
||||
|
||||
all: $(BINEXECS)
|
||||
|
||||
$(BINDIR)/guest_scale_agent: $(GUEST_SCALE_AGENT_OBJ)
|
||||
$(CC) -o $@ $^ $(LDFLAGS) -lguesthostmsg -ljson-c
|
||||
|
||||
clean:
|
||||
rm -rf $(ODIR)/* *~ core $(BINDIR)/*
|
||||
@@ -0,0 +1,4 @@
|
||||
# Ignore everything in this directory
|
||||
*
|
||||
# Except this file
|
||||
!.gitignore
|
||||
@@ -0,0 +1,243 @@
|
||||
BSD LICENSE
|
||||
|
||||
Copyright(c) 2013-2016, Wind River Systems, Inc.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
* Neither the name of Wind River Systems nor the names of its
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
-----------------------------------------------------------------------
|
||||
|
||||
DESCRIPTION
|
||||
===========
|
||||
Guest Server Scaling is a service to allow a guest to scale the capacity of a
|
||||
single guest server up and down on demand.
|
||||
|
||||
Current supported scaling operation is CPU scaling.
|
||||
|
||||
The resources can be scaled up/down from the nova CLI or GUI. Scaling can also
|
||||
be set up via heat to be automatically triggered based on Ceilometer statistics.
|
||||
(This will not be covered in this document, see the full documentation and the
|
||||
heat SDK for how to configure heat templates for scaling a single guest server.)
|
||||
|
||||
This package contains an agent and a number of scripts to be included in the
|
||||
guest image. These will handle the guest side of the coordinated efforts
|
||||
involved in scaling up/down guest resources.
|
||||
|
||||
|
||||
DEPENDENCIES
|
||||
============
|
||||
NOTE that this wrs-guest-scale SDK module has both a compile-time and run-time
|
||||
dependency on the wrs-server-group SDK module.
|
||||
|
||||
This wrs-guest-scale SDK module requires that the wrs-server-group SDK tarball
|
||||
has been previously extracted and built, and that the resulting libraries
|
||||
and headers have been placed in a location that can be found by the normal build
|
||||
tools, or the WRS_SERVER_GROUP_DIR environment variable has been set.
|
||||
|
||||
The output of BOTH the wrs-guest-scale SDK module and the wrs-server-group SDK
|
||||
module are required to be installed in a guest image for guest resource scaling.
|
||||
|
||||
|
||||
REQUIREMENTS
|
||||
============
|
||||
Compilation:
|
||||
Linux OS, x86_64 architecture
|
||||
gcc compiler
|
||||
development libraries and headers for glibc
|
||||
development libraries and headers for libguesthostmsg
|
||||
(built by the wrs-server-group SDK package)
|
||||
development libraries and headers for json-c
|
||||
|
||||
VM Runtime:
|
||||
Linux OS, x86_64 architecture; CONFIG_HOTPLUG_CPU=y|m
|
||||
runtime libraries for glibc
|
||||
runtime libraries for libguesthostmsg
|
||||
"guest_agent" binary daemon
|
||||
(provided by the wrs-server-group SDK package)
|
||||
runtime libraries for json-c
|
||||
|
||||
The code has been tested with glibc 2.15, gcc 4.6 and json-c 0.12.99 but it
|
||||
should run on other versions without difficulty.
|
||||
|
||||
|
||||
DELIVERABLE
|
||||
===========
|
||||
The Guest Server Scaling service is delivered as source with the required
|
||||
Makefiles in a compressed tarball called "wrs-guest-scale-#.#.#.tgz", such that
|
||||
it can be compiled for the applicable guest linux distribution.
|
||||
|
||||
|
||||
COMPILE
|
||||
=======
|
||||
Pre-requisite:
|
||||
Ensure that the wrs-server-group SDK tarball has been previously extracted and
|
||||
built, and that the resulting libraries and headers have been placed in a
|
||||
location that can be found by the normal build tools, or the WRS_SERVER_GROUP_DIR
|
||||
environment variable has been set.
|
||||
|
||||
Extract the tarball contents:
|
||||
|
||||
tar xvf wrs-guest-scale-#.#.#.tgz
|
||||
|
||||
To compile:
|
||||
|
||||
# Note: assumes wrs-server-group-#.#.#.tgz has already been extracted and compiled.
|
||||
|
||||
cd wrs-guest-scale-#.#.#
|
||||
|
||||
# If wrs-guest-scale-#.#.#.tgz and wrs-server-group-#.#.#.tgz where extracted in a common directory
|
||||
make
|
||||
|
||||
# Otherwise supply the path to where wrs-server-group can be found. e.g.
|
||||
make WRS_SERVER_GROUP_DIR=/usr/src/wrs-server-group-#.#.#
|
||||
|
||||
This will produce:
|
||||
|
||||
1) An executable "bin/guest_scale_agent". This handles the basic vCPU scaling
|
||||
in the guest, and calls out to a helper script if present to support
|
||||
application-specific customization. It should be configured to respawn
|
||||
(via /etc/inittab or some other process monitor) if it dies for any reason.
|
||||
This executable must be installed into the guest (e.g. in "/usr/sbin") and configured
|
||||
to run at startup as early as possible.
|
||||
NOTE
|
||||
The "guest_agent" executable from the wrs-server-group SDK package MUST ALSO
|
||||
be installed into the guest (e.g. in "/usr/bin"), configured to run at startup
|
||||
as early as possible and configured to respawn via /etc/inittab or some other
|
||||
process monitor (in case it dies for any reason).
|
||||
|
||||
2) A script "script/app_scale_helper". This is an optional script that is
|
||||
intended to allow for app-specific customization. If present, it must be
|
||||
installed in "/usr/sbin". If present, it will be called by "guest_scale_agent"
|
||||
when scaling in either direction.
|
||||
|
||||
3) A script "script/offline_cpus". This must be run later in the init sequence,
|
||||
after guest_scale_agent has started up but before the application has started
|
||||
any CPU-affined applications. A helper script "script/init_offline_cpus" has
|
||||
been provided, and should be installed to "/etc/init.d/offline_cpus. The
|
||||
"offline_cpus" script will offline vCPUs in the guest to match the status on
|
||||
the hypervisor. This covers the case where we are booting up with some CPUs
|
||||
offlined by the hypervisor.
|
||||
|
||||
4) For systemd users, the files "scripts/guest-scale-agent.service" and
|
||||
"scripts/offline-cpus.service" should be copied to /lib/systemd/system/.
|
||||
|
||||
|
||||
Note:
|
||||
The inclusion of the files into the build system and the guest image and the
|
||||
configuration of the guest startup scripts is left up to the user to allow for
|
||||
different build systems and init subsystems in the guest.
|
||||
|
||||
|
||||
INSTALL
|
||||
=======
|
||||
Installing in a running VM:
|
||||
|
||||
As the root user
|
||||
1) Copy "bin/guest_scale_agent" to /usr/sbin in the VM.
|
||||
|
||||
2) Copy "scripts/app_scale_helper" and "scripts/offline_cpus" to /usr/sbin in the VM.
|
||||
|
||||
3) Copy "scripts/init_offline_cpus" to "/etc/init.d/offline_cpus". (Note the name change.)
|
||||
|
||||
4) Copy "scripts/guest-scale-agent.service" and "scripts/offline-cpus.service" to
|
||||
/lib/systemd/system/.
|
||||
|
||||
5) Run "systemctl enable guest-scale-agent.service", "systemctl enable offline-cpus.service",
|
||||
"systemctl start guest-scale-agent.service", "systemctl start offline-cpus.service"
|
||||
|
||||
The VM should now be ready to scale up and down.
|
||||
|
||||
|
||||
USAGE
|
||||
=====
|
||||
The service is designed to be simple to use. A basic description is given
|
||||
below, but more details are provided in the source and scripts.
|
||||
|
||||
1) Create a new flavor (or edit an existing flavor) such that the number of
|
||||
vCPUs in the flavor matches the desired maximum number of vCPUs. To specify the
|
||||
minimum number of vCPUs, create an "extra spec" metadata entry for the flavor
|
||||
with a key of "wrs:min_vcpus" and a value that is an integer number between one
|
||||
and the max number of vCPUs. This can be done from the CLI or the GUI. (In the
|
||||
GUI select the "Admin" tab, go to the "Flavor" navigation link, click on a
|
||||
flavor name, select the "Extra Specs" tab, click on "Create", select
|
||||
"Minimum Number of CPUs" from the pulldown, and enter the desired value.)
|
||||
|
||||
2) Build BOTH the wrs-server-group SDK package and this wrs-guest-scale package,
|
||||
and install the output of BOTH packages in an image. Lastly, ensure that the
|
||||
CONFIG_HOTPLUG_CPU kernel config option is set in the image kernel.
|
||||
|
||||
3) Boot the image. It will come up with the full set of vCPUs.
|
||||
|
||||
4) To reduce the number of online vCPUs in the guest server, run
|
||||
"nova scale <server> cpu down" from the controller (or anywhere else you can run
|
||||
nova commands). This will pass a message up into the guest, where it will be
|
||||
handled by "guest_scale_agent". That in turn will call out to
|
||||
"/usr/sbin/app_scale_helper" (if it exists) which is expected to pick a vCPU to
|
||||
offline. This script can be modified/replaced as needed for application-
|
||||
specific purposes. By default, it will select the highest-numbered online vCPU.
|
||||
If the script isn't present or errors out, then "guest_scale_agent" will itself
|
||||
select the highest-numbered online vCPU as the one to be offlined. It will then
|
||||
tell the guest kernel to offline the selected vCPU, and will pass the selected
|
||||
vCPU back down to the hypervisor, which will adjust vCPU affinity so that the
|
||||
underlying physical CPU can be freed up for use by other VMs. At this point
|
||||
displaying the information for the guest server will show it using less than the
|
||||
maximum number of cpus.
|
||||
|
||||
5) To increase the number of online vCPUs, run "nova scale <server> cpu up".
|
||||
Assuming the resources are available the hypervisor will allocate a physical CPU
|
||||
and will associate it with the guest server. "guest_scale_agent" will set the
|
||||
lowest-numbered offline vCPU to "online", and will pass the vCPU number to
|
||||
"/usr/sbin/app_scale_helper" (if it exists) for the application to do any
|
||||
special handling that may be required.
|
||||
|
||||
|
||||
The behaviour of a scaled-down server during various nova operations is as
|
||||
follows:
|
||||
|
||||
live migration: server remains scaled-down
|
||||
pause/unpause: server remains scaled-down
|
||||
stop/start: server remains scaled-down
|
||||
evacuation: server remains scaled-down
|
||||
rebuild: server remains scaled-down
|
||||
automatic restart on crash: server remains scaled-down
|
||||
cold migration: server reverts to max vcpus
|
||||
resize: server reverts to max vcpus for the new flavor
|
||||
|
||||
If a snapshot is taken of a scaled-down server, a new server booting the
|
||||
snapshot will start with the number of vCPUs specified by the flavor.
|
||||
|
||||
CAVEATS
|
||||
=======
|
||||
It is possible for the scale-up operation to fail if the compute node has
|
||||
already allocated all of its resources to other guests. If this happens,
|
||||
the system will not do any automatic migration to try to free up resources.
|
||||
Manual action will be required to free up resources.
|
||||
|
||||
Any CPUs that are handling userspace DPDK/AVP packet processing should not be
|
||||
offlined. It may appear to work, but may lead to packet loss. This can be
|
||||
enforced by setting the wrs:min_vcpus value appropriately high.
|
||||
|
||||
If hyperthreading is used, the flavor must set hw:cpu_thread_policy to
|
||||
isolate and set cpu_policy to dedicated.
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,515 @@
|
||||
/**
|
||||
* Copyright (c) <2013-2016>, Wind River Systems, Inc.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1) Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2) Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* 3) Neither the name of Wind River Systems nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software without specific
|
||||
* prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <error.h>
|
||||
#include <fcntl.h>
|
||||
#include <poll.h>
|
||||
#include <pthread.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <inttypes.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/select.h>
|
||||
#include <cgcs/guest_host_msg.h>
|
||||
#include <json-c/json.h>
|
||||
|
||||
#include "misc.h"
|
||||
|
||||
gh_info_t *info;
|
||||
|
||||
/* Scaling Request/Response message is encoded in JSON format.
|
||||
The message sent out to UNIX socket is a null-terminated JSON format string
|
||||
without embedded newlines.
|
||||
|
||||
Format:
|
||||
{key:value,key:value,..., key:value}
|
||||
|
||||
Key/value pairs for Scaling Request:
|
||||
"version": <integer> - version of the interface
|
||||
"timeout_ms": <integer> - timeout for app_scale_helper scripts
|
||||
"resource": “cpu” - indicate the resouce to scale.
|
||||
Only cpu is currently supported.
|
||||
"direction“: "up” or “down”
|
||||
"online_cpu": <integer> - vcpu number to online when scale up
|
||||
"online_cpus": <array of integers> - array of current online cpus
|
||||
when request was sent.
|
||||
example: [0,1,2,3,4,5]
|
||||
|
||||
Key/value pairs for Scaling Response:
|
||||
"version": <integer>
|
||||
"resource": “cpu”
|
||||
"direction“: "up” or “down”
|
||||
"online_cpu": <integer> - vcpu number to online when scale up
|
||||
"offline_cpu": <integer> - actual offlined vcpu number
|
||||
"online_cpus": <array of integers> - array of current online cpus
|
||||
when response was sent.
|
||||
"result": "success" or "fail"
|
||||
"err_msg": <string> - error message if result is fail
|
||||
|
||||
*/
|
||||
|
||||
#define CPU_SCRIPT "/usr/sbin/app_scale_helper"
|
||||
|
||||
// generic function to call out to helper script
|
||||
// need to add support for timeout in here in case script hangs
|
||||
int call_helper_script(char *cmd, int timeout_ms)
|
||||
{
|
||||
FILE *fp;
|
||||
int rc;
|
||||
|
||||
fp = popen(cmd, "w");
|
||||
if (fp) {
|
||||
rc = pclose(fp);
|
||||
if (rc == -1) {
|
||||
ERR_LOG("pclose failed: %m");
|
||||
return -1;
|
||||
} else {
|
||||
if (WIFEXITED(rc)) {
|
||||
rc = WEXITSTATUS(rc);
|
||||
if (rc == 127) {
|
||||
ERR_LOG("problem with shell or helper script, possibly script missing");
|
||||
return -1;
|
||||
} else
|
||||
return rc;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ERR_LOG("popen failed due to fork/pipe/memory");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int online_cpu(unsigned cpu)
|
||||
{
|
||||
int fd;
|
||||
int rc;
|
||||
char buf[100];
|
||||
char val;
|
||||
snprintf(buf, sizeof(buf), "/sys/devices/system/cpu/cpu%u/online", cpu);
|
||||
fd = open(buf, O_RDWR);
|
||||
if (fd < 0) {
|
||||
ERR_LOG("can't open cpu online path: %m");
|
||||
return -1;
|
||||
}
|
||||
rc = read(fd, &val, 1);
|
||||
if (rc != 1){
|
||||
ERR_LOG("can't read cpu online value: %m");
|
||||
return -1;
|
||||
}
|
||||
if (val == '1') {
|
||||
ERR_LOG("cpu %d is already online", cpu);
|
||||
return 0;
|
||||
}
|
||||
val = '1';
|
||||
rc = write(fd, &val, 1);
|
||||
if (rc != 1){
|
||||
ERR_LOG("can't set cpu %d online", cpu);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int offline_cpu(unsigned cpu)
|
||||
{
|
||||
int fd;
|
||||
int rc;
|
||||
char buf[100];
|
||||
char val;
|
||||
snprintf(buf, sizeof(buf), "/sys/devices/system/cpu/cpu%u/online", cpu);
|
||||
fd = open(buf, O_RDWR);
|
||||
if (fd < 0) {
|
||||
ERR_LOG("can't open cpu online path: %m");
|
||||
return -1;
|
||||
}
|
||||
rc = read(fd, &val, 1);
|
||||
if (rc != 1){
|
||||
ERR_LOG("can't read cpu online value: %m");
|
||||
return -1;
|
||||
}
|
||||
if (val == '0') {
|
||||
ERR_LOG("cpu %d is already offline\n", cpu);
|
||||
return 0;
|
||||
}
|
||||
val = '0';
|
||||
rc = write(fd, &val, 1);
|
||||
if (rc != 1){
|
||||
ERR_LOG("can't set cpu %d offline", cpu);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// read /sys/devices/system/cpu/online and get the last cpu listed
|
||||
int get_highest_online_cpu(void)
|
||||
{
|
||||
int fd, rc;
|
||||
char buf[256];
|
||||
char *start;
|
||||
unsigned int cpu;
|
||||
fd = open("/sys/devices/system/cpu/online", O_RDONLY);
|
||||
if (fd < 0) {
|
||||
ERR_LOG("can't fopen /sys/devices/system/cpu/online: %m");
|
||||
return -1;
|
||||
}
|
||||
|
||||
rc = read(fd, buf, sizeof(buf));
|
||||
if (rc < 2) {
|
||||
ERR_LOG("error parsing /sys/devices/system/cpu/online, too few chars");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// go to the end of the string
|
||||
start = buf+rc-1;
|
||||
if(*start != '\n') {
|
||||
ERR_LOG("error parsing /sys/devices/system/cpu/online, not null-terminated");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// now go backwards until we get to a separator or the beginning of the string
|
||||
while ((*start != ',') && (*start != '-') && (start != buf))
|
||||
start--;
|
||||
|
||||
start++;
|
||||
rc = sscanf(start, "%u", &cpu);
|
||||
if (rc != 1) {
|
||||
ERR_LOG("error parsing /sys/devices/system/cpu/online, bad number");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return cpu;
|
||||
}
|
||||
|
||||
|
||||
char *get_online_cpu_range(void)
|
||||
{
|
||||
FILE *file;
|
||||
int rc;
|
||||
char *str = NULL;
|
||||
file = fopen("/sys/devices/system/cpu/online", "r");
|
||||
if (!file) {
|
||||
ERR_LOG("can't fopen /sys/devices/system/cpu/online: %m");
|
||||
return 0;
|
||||
}
|
||||
rc = fscanf(file, "%ms", &str);
|
||||
if (rc != 1)
|
||||
ERR_LOG("can't read /sys/devices/system/cpu/online: %m");
|
||||
fclose(file);
|
||||
return str;
|
||||
}
|
||||
|
||||
|
||||
void cpu_scale_down(json_object *jobj_request,
|
||||
json_object *jobj_response)
|
||||
{
|
||||
char cmd[1000];
|
||||
int cpu=-1;
|
||||
int rc;
|
||||
|
||||
//build our command to send to the helper script
|
||||
rc = snprintf(cmd, sizeof(cmd), "%s --cpu_del\n", CPU_SCRIPT);
|
||||
if ((rc > sizeof(cmd)) || rc < 0) {
|
||||
ERR_LOG("error generating command: %m");
|
||||
goto pick_cpu;
|
||||
}
|
||||
|
||||
struct json_object *jobj_timeout_ms;
|
||||
int timeout_ms;
|
||||
if (!json_object_object_get_ex(jobj_request, TIMEOUT_MS, &jobj_timeout_ms))
|
||||
{
|
||||
ERR_LOG("failed to parse timeout_ms");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
errno = 0;
|
||||
timeout_ms = json_object_get_int(jobj_timeout_ms);
|
||||
if(errno){
|
||||
ERR_LOG("Error converting timeout_ms: %s", strerror(errno));
|
||||
goto failed;
|
||||
}
|
||||
|
||||
// call app helper script to select cpu to offline
|
||||
rc = call_helper_script(cmd, timeout_ms);
|
||||
if (rc < 0) {
|
||||
ERR_LOG("call to app helper script failed\n");
|
||||
goto pick_cpu;
|
||||
} else if (rc == 0) {
|
||||
ERR_LOG("call to app helper script return invalid cpu number 0\n");
|
||||
goto pick_cpu;
|
||||
} else {
|
||||
INFO_LOG("app helper script chose cpu %d to offline\n", rc);
|
||||
cpu = rc;
|
||||
}
|
||||
|
||||
pick_cpu:
|
||||
// if the app helper script doesn't exist or didn't return
|
||||
// a cpu to offline, pick one ourselves
|
||||
if (cpu == -1) {
|
||||
cpu = get_highest_online_cpu();
|
||||
if (cpu <= 0) {
|
||||
ERR_LOG("unable to find cpu to offline\n");
|
||||
goto failed;
|
||||
}
|
||||
}
|
||||
|
||||
// try to offline selected cpu
|
||||
rc = offline_cpu(cpu);
|
||||
if (rc < 0) {
|
||||
ERR_LOG("failed to set cpu %d offline\n", cpu);
|
||||
goto failed;
|
||||
}
|
||||
|
||||
INFO_LOG("set cpu %d offline", cpu);
|
||||
|
||||
// we have successfully offlined the cpu
|
||||
json_object_object_add(jobj_response, RESULT, json_object_new_string("success"));
|
||||
json_object_object_add(jobj_response, OFFLINE_CPU, json_object_new_int(cpu));
|
||||
struct online_cpus *current_online_cpus = range_to_array(get_online_cpu_range());
|
||||
|
||||
// no need to release jobj_array as its ownership is transferred to jobj_response
|
||||
struct json_object *jobj_array = new_json_obj_from_array(current_online_cpus);
|
||||
json_object_object_add(jobj_response, ONLINE_CPUS, jobj_array);
|
||||
return;
|
||||
|
||||
failed:
|
||||
json_object_object_add(jobj_response, RESULT, json_object_new_string("fail"));
|
||||
json_object_object_add(jobj_response, ERR_MSG, json_object_new_string(errorbuf));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
void cpu_scale_up(json_object *jobj_request,
|
||||
json_object *jobj_response)
|
||||
{
|
||||
char cmd[1000];
|
||||
struct json_object *jobj_timeout_ms;
|
||||
if (!json_object_object_get_ex(jobj_request, TIMEOUT_MS, &jobj_timeout_ms)) {
|
||||
ERR_LOG("failed to parse timeout_ms");
|
||||
goto failed;
|
||||
}
|
||||
int timeout_ms = json_object_get_int(jobj_timeout_ms);
|
||||
|
||||
struct json_object *jobj_cpu;
|
||||
if (!json_object_object_get_ex(jobj_request, ONLINE_CPU, &jobj_cpu)) {
|
||||
ERR_LOG("failed to parse online_cpu");
|
||||
goto failed;
|
||||
}
|
||||
int cpu = json_object_get_int(jobj_cpu);
|
||||
|
||||
//online_cpus is optional
|
||||
struct json_object *jobj_online_cpus;
|
||||
const char *online_cpus;
|
||||
if (!json_object_object_get_ex(jobj_request, ONLINE_CPUS, &jobj_online_cpus)) {
|
||||
ERR_LOG("failed to parse online_cpus");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
json_object_object_get_ex(jobj_request, ONLINE_CPUS, &jobj_online_cpus);
|
||||
if (!json_object_is_type(jobj_online_cpus, json_type_array)) {
|
||||
ERR_LOG("failed to parse online_cpus");
|
||||
goto failed;
|
||||
}
|
||||
online_cpus = json_object_to_json_string_ext(jobj_online_cpus, JSON_C_TO_STRING_PLAIN);
|
||||
|
||||
int rc = online_cpu(cpu);
|
||||
if (rc < 0) {
|
||||
printf("failed to set cpu %d online\n", cpu);
|
||||
goto failed;
|
||||
}
|
||||
|
||||
INFO_LOG("set cpu %d online", cpu);
|
||||
|
||||
// Now try to call out to the helper script
|
||||
// If it fails, not the end of the world.
|
||||
|
||||
rc = snprintf(cmd, sizeof(cmd), "%s --cpu_add %d %s\n",
|
||||
CPU_SCRIPT, cpu, online_cpus);
|
||||
|
||||
if ((rc > 0) && (rc < sizeof(cmd))) {
|
||||
rc = call_helper_script(cmd, timeout_ms);
|
||||
if (rc != 0)
|
||||
ERR_LOG("call to app helper script failed, return code: %d\n", rc);
|
||||
} else
|
||||
ERR_LOG("error generating command: %m");
|
||||
|
||||
json_object_object_add(jobj_response, RESULT, json_object_new_string("success"));
|
||||
json_object_object_add(jobj_response, ONLINE_CPU, json_object_new_int(cpu));
|
||||
struct online_cpus *current_online_cpus = range_to_array(get_online_cpu_range());
|
||||
|
||||
// no need to release jobj_array as its ownership is transferred to jobj_response
|
||||
struct json_object *jobj_array = new_json_obj_from_array(current_online_cpus);
|
||||
json_object_object_add(jobj_response, ONLINE_CPUS, jobj_array);
|
||||
|
||||
return;
|
||||
|
||||
failed:
|
||||
json_object_object_add(jobj_response, RESULT, json_object_new_string("fail"));
|
||||
json_object_object_add(jobj_response, ERR_MSG, json_object_new_string(errorbuf));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* Callback message handler. This will be called by the generic guest/host
|
||||
* messaging library when a valid message arrives from the host.
|
||||
*/
|
||||
void msg_handler(const char *source_addr, json_object *jobj_request)
|
||||
{
|
||||
int rc;
|
||||
|
||||
// parse version
|
||||
struct json_object *jobj_version;
|
||||
if (!json_object_object_get_ex(jobj_request, VERSION, &jobj_version)) {
|
||||
ERR_LOG("failed to parse version");
|
||||
return;
|
||||
}
|
||||
int version = json_object_get_int(jobj_version);
|
||||
|
||||
if (version != CUR_VERSION) {
|
||||
ERR_LOG("invalid version %d, expecting %d", version, CUR_VERSION);
|
||||
return;
|
||||
}
|
||||
|
||||
// parse msg_type
|
||||
struct json_object *jobj_msg_type;
|
||||
if (!json_object_object_get_ex(jobj_request, MSG_TYPE, &jobj_msg_type)) {
|
||||
ERR_LOG("failed to parse msg_type");
|
||||
return;
|
||||
}
|
||||
const char *msg_type = json_object_get_string(jobj_msg_type);
|
||||
|
||||
if (!strcmp(msg_type, MSG_TYPE_NACK)) {
|
||||
struct json_object *jobj_log_msg;
|
||||
if (!json_object_object_get_ex(jobj_request, LOG_MSG, &jobj_log_msg)) {
|
||||
ERR_LOG("Nack: failed to parse log_msg");
|
||||
}
|
||||
const char *log_msg = json_object_get_string(jobj_log_msg);
|
||||
ERR_LOG("Nack received, error message from host: %s", log_msg);
|
||||
return;
|
||||
} else if (!strcmp(msg_type, MSG_TYPE_SCALE_REQUEST)) {
|
||||
;
|
||||
} else {
|
||||
ERR_LOG("unknown message type: %s", msg_type);
|
||||
return;
|
||||
}
|
||||
|
||||
struct json_object *jobj_response = json_object_new_object();
|
||||
if (jobj_response == NULL) {
|
||||
ERR_LOG("failed to allocate json object for response");
|
||||
return;
|
||||
}
|
||||
|
||||
struct json_object *jobj_resource;
|
||||
if (!json_object_object_get_ex(jobj_request, RESOURCE, &jobj_resource)) {
|
||||
ERR_LOG("failed to parse resource");
|
||||
goto done;
|
||||
}
|
||||
const char *resource = json_object_get_string(jobj_resource);
|
||||
|
||||
struct json_object *jobj_direction;
|
||||
if (!json_object_object_get_ex(jobj_request, DIRECTION, &jobj_direction)) {
|
||||
ERR_LOG("failed to parse direction'");
|
||||
goto done;
|
||||
}
|
||||
const char *direction = json_object_get_string(jobj_direction);
|
||||
|
||||
rc = -1;
|
||||
if (!strcmp(resource,"cpu")) {
|
||||
if (!strcmp(direction,"up")) {
|
||||
cpu_scale_up(jobj_request, jobj_response);
|
||||
} else if (!strcmp(direction,"down")) {
|
||||
cpu_scale_down(jobj_request, jobj_response);
|
||||
}
|
||||
}
|
||||
|
||||
json_object_object_add(jobj_response, VERSION, json_object_new_int(CUR_VERSION));
|
||||
json_object_object_add(jobj_response, RESOURCE, jobj_resource);
|
||||
json_object_object_add(jobj_response, DIRECTION, jobj_direction);
|
||||
|
||||
const char *response = json_object_to_json_string_ext(jobj_response, JSON_C_TO_STRING_PLAIN);
|
||||
|
||||
// Send response back to the sender.
|
||||
rc = gh_send_msg(info, source_addr, response);
|
||||
if (rc < 0) {
|
||||
ERR_LOG("gh_send_msg failed: %s\n", gh_get_error(info));
|
||||
return;
|
||||
}
|
||||
done:
|
||||
json_object_put(jobj_response);
|
||||
}
|
||||
|
||||
|
||||
void wait_for_messages(int fd)
|
||||
{
|
||||
int rc;
|
||||
fd_set rfds, rfds_tmp;
|
||||
|
||||
FD_ZERO(&rfds);
|
||||
FD_SET(fd, &rfds);
|
||||
|
||||
while(1) {
|
||||
rfds_tmp = rfds;
|
||||
rc = select(fd+1, &rfds_tmp, NULL, NULL, NULL);
|
||||
if (rc > 0) {
|
||||
if (gh_process_msg(info) < 0) {
|
||||
ERR_LOG("problem processing messages: %s\n",
|
||||
gh_get_error(info));
|
||||
}
|
||||
} else if (rc < 0) {
|
||||
ERR_LOG("select(): %m");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
int fd = gh_init(msg_handler, SCALE_AGENT_ADDR, &info);
|
||||
if (fd == -1) {
|
||||
if (!info)
|
||||
ERR_LOG("Unable to allocate memory for info: %m");
|
||||
else
|
||||
ERR_LOG("Unable to initialize guest/host messaging: %s\n",
|
||||
gh_get_error(info));
|
||||
return -1;
|
||||
}
|
||||
INFO_LOG("Running offline_cpus script");
|
||||
system("offline_cpus");
|
||||
wait_for_messages(fd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,534 @@
|
||||
/**
|
||||
* Copyright (c) <2013-2016>, Wind River Systems, Inc.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1) Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2) Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* 3) Neither the name of Wind River Systems nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software without specific
|
||||
* prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/* This is intended to run as a helper function, called by nova, to pass data up
|
||||
* into the guest and receive data back from the guest and return it to nova.
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stddef.h>
|
||||
#include <sys/time.h>
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
#include <cgcs/host_guest_msg.h>
|
||||
#include <json-c/json.h>
|
||||
|
||||
#include "misc.h"
|
||||
|
||||
hg_info_t *info;
|
||||
|
||||
#define SPARE_ALLOC 128
|
||||
|
||||
#define INSTANCE_NAME_SIZE 32
|
||||
#define NACK_LOG_SIZE 500
|
||||
|
||||
#define UNIX_ADDR_LEN 16
|
||||
#define DEFAULT_TIMEOUT_MS 1000
|
||||
#define TIMEOUT_OVERHEAD_MS 500
|
||||
#define MIN_SCRIPT_TIMEOUT_MS 500
|
||||
int timeout_ms = DEFAULT_TIMEOUT_MS;
|
||||
|
||||
int *request_online_cpus;
|
||||
int len_request_online_cpus;
|
||||
int request_cpu;
|
||||
|
||||
void usage() {
|
||||
printf("guest_scale_helper --instance_name <name>\n");
|
||||
printf(" --cpu_del | --cpu_add <index> <cur_mask>\n");
|
||||
printf(" [--timeout <millisec, at least 1000>]\n");
|
||||
printf("\n");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
void handle_cpu_scale_up(json_object *jobj_response, const char *source_instance)
|
||||
{
|
||||
int rc = -1;
|
||||
char log_msg[NACK_LOG_SIZE];
|
||||
|
||||
struct json_object *jobj_result;
|
||||
if (!json_object_object_get_ex(jobj_response, RESULT, &jobj_result)) {
|
||||
snprintf(log_msg, NACK_LOG_SIZE, "failed to parse result");
|
||||
goto failed;
|
||||
}
|
||||
const char *result = json_object_get_string(jobj_result);
|
||||
|
||||
if (!strcmp(result, "fail")) {
|
||||
struct json_object *jobj_err_msg;
|
||||
const char *err_msg;
|
||||
|
||||
if (!json_object_object_get_ex(jobj_response, ERR_MSG, &jobj_err_msg))
|
||||
err_msg="";
|
||||
else
|
||||
err_msg = json_object_get_string(jobj_err_msg);
|
||||
ERR_LOG("Error: guest helper scaling cpu up failed: %s\n", err_msg);
|
||||
goto out;
|
||||
}
|
||||
|
||||
struct json_object *jobj_online_cpu;
|
||||
if (!json_object_object_get_ex(jobj_response, ONLINE_CPU, &jobj_online_cpu)) {
|
||||
snprintf(log_msg, NACK_LOG_SIZE, "failed to parse online_cpu");
|
||||
goto failed;
|
||||
}
|
||||
int online_cpu = json_object_get_int(jobj_online_cpu);
|
||||
|
||||
struct json_object *jobj_online_cpus;
|
||||
|
||||
json_object_object_get_ex(jobj_response, ONLINE_CPUS, &jobj_online_cpus);
|
||||
if (!json_object_is_type(jobj_online_cpus, json_type_array)) {
|
||||
snprintf(log_msg, NACK_LOG_SIZE, "failed to parse online_cpus");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
int i, len_response;
|
||||
len_response = json_object_array_length(jobj_online_cpus);
|
||||
int *response_online_cpus = malloc(len_response*sizeof(int));
|
||||
|
||||
for (i=0; i< len_response; i++){
|
||||
response_online_cpus[i] = json_object_get_int(json_object_array_get_idx(jobj_online_cpus, i));
|
||||
}
|
||||
|
||||
// compare request and response, assuming cpus are in the same order
|
||||
if ( (len_response - len_request_online_cpus ) <=1 ) {
|
||||
int req =0;
|
||||
int rsp = 0;
|
||||
int found_req = 0;
|
||||
while (req < len_request_online_cpus){
|
||||
|
||||
if (response_online_cpus[rsp] == request_online_cpus[req]) {
|
||||
req++; rsp++;
|
||||
} else if (response_online_cpus[rsp] == request_cpu) {
|
||||
rsp++;
|
||||
found_req = 1;
|
||||
// protect against infinite loop
|
||||
if (rsp == len_response)
|
||||
break;
|
||||
} else {
|
||||
ERR_LOG("Error: cpu %d online by guest but not online in nova\n", response_online_cpus[rsp]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ((!found_req) && (req == len_request_online_cpus)) {
|
||||
if ((len_response == len_request_online_cpus) ||
|
||||
(response_online_cpus[len_response] != request_cpu)) {
|
||||
ERR_LOG("Error: cpu %d online by nova but not online in guest\n", response_online_cpus[req]);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
ERR_LOG("Error: guest's online cpu range doesn't match nova\n");
|
||||
char buf[1024];
|
||||
print_array(buf, response_online_cpus, len_response);
|
||||
ERR_LOG("guest online cpu range: %s\n", buf);
|
||||
}
|
||||
|
||||
// Yay, everything looks good.
|
||||
free(response_online_cpus);
|
||||
free(request_online_cpus);
|
||||
exit(online_cpu);
|
||||
rc = online_cpu;
|
||||
failed:
|
||||
send_nack(log_msg, source_instance);
|
||||
out:
|
||||
free(request_online_cpus);
|
||||
exit(rc);
|
||||
}
|
||||
|
||||
|
||||
void handle_cpu_scale_down(json_object *jobj_response, const char *source_instance)
|
||||
{
|
||||
int rc = -1;
|
||||
struct json_object *jobj_result;
|
||||
char log_msg[NACK_LOG_SIZE];
|
||||
|
||||
if (!json_object_object_get_ex(jobj_response, RESULT, &jobj_result)) {
|
||||
snprintf(log_msg, NACK_LOG_SIZE, "failed to parse result");
|
||||
goto failed;
|
||||
}
|
||||
const char *result = json_object_get_string(jobj_result);
|
||||
|
||||
if (!strcmp(result, "fail")) {
|
||||
struct json_object *jobj_err_msg;
|
||||
const char *err_msg;
|
||||
if (!json_object_object_get_ex(jobj_response, ERR_MSG, &jobj_err_msg))
|
||||
err_msg="";
|
||||
else
|
||||
err_msg = json_object_get_string(jobj_err_msg);
|
||||
ERR_LOG("problem, guest helper scaling cpu down failed: %s\n", err_msg);
|
||||
goto out;
|
||||
}
|
||||
|
||||
struct json_object *jobj_offline_cpu;
|
||||
if (!json_object_object_get_ex(jobj_response, OFFLINE_CPU, &jobj_offline_cpu)) {
|
||||
snprintf(log_msg, NACK_LOG_SIZE, "failed to parse offline_cpu");
|
||||
goto failed;
|
||||
}
|
||||
int offline_cpu = json_object_get_int(jobj_offline_cpu);
|
||||
|
||||
struct json_object *jobj_online_cpus;
|
||||
json_object_object_get_ex(jobj_response, ONLINE_CPUS, &jobj_online_cpus);
|
||||
if (!json_object_is_type(jobj_online_cpus, json_type_array)) {
|
||||
snprintf(log_msg, NACK_LOG_SIZE, "failed to parse online_cpus");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
int i, len_response;
|
||||
len_response = json_object_array_length(jobj_online_cpus);
|
||||
int *response_online_cpus = malloc(len_response*sizeof(int));
|
||||
|
||||
for (i=0; i< len_response; i++){
|
||||
response_online_cpus[i] = json_object_get_int(json_object_array_get_idx(jobj_online_cpus, i));
|
||||
}
|
||||
|
||||
if (response_online_cpus[len_response] > offline_cpu) {
|
||||
ERR_LOG("Error: cpu %d is still online in guest\n", offline_cpu);
|
||||
}
|
||||
|
||||
// Yay, everything looks good.
|
||||
free(response_online_cpus);
|
||||
free(request_online_cpus);
|
||||
rc = offline_cpu;
|
||||
exit(rc);
|
||||
failed:
|
||||
send_nack(log_msg, source_instance);
|
||||
out:
|
||||
free(request_online_cpus);
|
||||
exit(rc);
|
||||
}
|
||||
|
||||
// This should call exit(0) on success or exit(-1) on permanent failure().
|
||||
// Returning will continue listening.
|
||||
// Theoretically this could come from any instance, need to fix that.
|
||||
void msg_handler(const char *source_addr, const char *source_instance, struct json_object *jobj_response)
|
||||
{
|
||||
// parse version
|
||||
struct json_object *jobj_version;
|
||||
char log_msg[NACK_LOG_SIZE];
|
||||
|
||||
if (!json_object_object_get_ex(jobj_response, VERSION, &jobj_version)) {
|
||||
snprintf(log_msg, NACK_LOG_SIZE, "failed to parse version");
|
||||
goto failed;
|
||||
}
|
||||
int version = json_object_get_int(jobj_version);
|
||||
|
||||
if (version != CUR_VERSION) {
|
||||
snprintf(log_msg, NACK_LOG_SIZE, "invalid version %d, expecting %d", version, CUR_VERSION);
|
||||
goto failed;
|
||||
}
|
||||
|
||||
struct json_object *jobj_resource;
|
||||
if (!json_object_object_get_ex(jobj_response, RESOURCE, &jobj_resource)) {
|
||||
snprintf(log_msg, NACK_LOG_SIZE, "failed to parse resource");
|
||||
goto failed;
|
||||
}
|
||||
const char *resource = json_object_get_string(jobj_resource);
|
||||
|
||||
struct json_object *jobj_direction;
|
||||
if (!json_object_object_get_ex(jobj_response, DIRECTION, &jobj_direction)) {
|
||||
snprintf(log_msg, NACK_LOG_SIZE, "failed to parse direction");
|
||||
goto failed;
|
||||
}
|
||||
const char *direction = json_object_get_string(jobj_direction);
|
||||
|
||||
if (!strcmp(resource,"cpu")) {
|
||||
if (!strcmp(direction,"up")) {
|
||||
handle_cpu_scale_up(jobj_response, source_instance);
|
||||
} else if (!strcmp(direction,"down")) {
|
||||
handle_cpu_scale_down(jobj_response, source_instance);
|
||||
}
|
||||
}
|
||||
|
||||
// if handle_cpu_scale_up/down is called, program should exit,
|
||||
// so this is only called when scale up/down are not properly handled.
|
||||
sprintf(log_msg, "unknown message, resource %s, direction %s",
|
||||
resource, direction);
|
||||
|
||||
failed:
|
||||
send_nack(log_msg, source_instance);
|
||||
}
|
||||
|
||||
// instance_name will be of the form instance-xxxxxxxx
|
||||
// We want to make a name of the form scale-xxxxxxxx
|
||||
void instance_to_addr(const char *instance_name, char *addr)
|
||||
{
|
||||
const char *match = "instance-";
|
||||
const char *replace = "scale-";
|
||||
char *tmp = strstr(instance_name, match);
|
||||
if (!tmp) {
|
||||
ERR_LOG("Instance name %s doesn't match expected pattern\n",
|
||||
instance_name);
|
||||
exit(-1);
|
||||
}
|
||||
strcpy(addr, replace);
|
||||
strncpy(addr+strlen(replace), instance_name+strlen(match),
|
||||
UNIX_ADDR_LEN-strlen(replace)-1);
|
||||
addr[UNIX_ADDR_LEN-1]='\0';
|
||||
}
|
||||
|
||||
void handle_message(const char *request, const char *instance_name)
|
||||
{
|
||||
int rc;
|
||||
fd_set rfds, rfds_tmp;
|
||||
int fd;
|
||||
char addr[UNIX_ADDR_LEN];
|
||||
|
||||
INFO_LOG("handling scaling request: %s", request);
|
||||
|
||||
// Create a unique address from the instance name. When using a helper app
|
||||
// this is needed in order to handle simultaneous scale events for different
|
||||
// servers on the same hypervisor.
|
||||
instance_to_addr(instance_name, addr);
|
||||
|
||||
fd = hg_init(msg_handler, addr, &info);
|
||||
if (fd == -1) {
|
||||
if (!info)
|
||||
ERR_LOG("Unable to allocate memory for info: %m");
|
||||
else
|
||||
ERR_LOG("Unable to initialize guest/host messaging: %s\n",
|
||||
hg_get_error(info));
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
rc = hg_send_msg(info, SCALE_AGENT_ADDR, instance_name, request);
|
||||
if (rc < 0) {
|
||||
ERR_LOG("hg_send_msg failed: %s\n", hg_get_error(info));
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
FD_ZERO(&rfds);
|
||||
FD_SET(fd, &rfds);
|
||||
|
||||
while(1) {
|
||||
rfds_tmp = rfds;
|
||||
rc = select(fd+1, &rfds_tmp, NULL, NULL, NULL);
|
||||
if (rc > 0) {
|
||||
if (hg_process_msg(info) < 0) {
|
||||
ERR_LOG("problem processing messages: %s\n",
|
||||
hg_get_error(info));
|
||||
}
|
||||
} else if (rc < 0) {
|
||||
ERR_LOG("select(): %m");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void send_nack(char *log_msg, const char *instance_name)
|
||||
{
|
||||
ERR_LOG("sending Nack with error: %s\n", log_msg);
|
||||
struct json_object *jobj_msg = json_object_new_object();
|
||||
if (jobj_msg == NULL) {
|
||||
ERR_LOG("failed to allocate json object for nack msg\n");
|
||||
return;
|
||||
}
|
||||
|
||||
json_object_object_add(jobj_msg, VERSION, json_object_new_int(CUR_VERSION));
|
||||
json_object_object_add(jobj_msg, MSG_TYPE, json_object_new_string(MSG_TYPE_NACK));
|
||||
json_object_object_add(jobj_msg, LOG_MSG, json_object_new_string(log_msg));
|
||||
|
||||
const char *msg = json_object_to_json_string_ext(jobj_msg, JSON_C_TO_STRING_PLAIN);
|
||||
hg_send_msg(info, SCALE_AGENT_ADDR, instance_name, msg);
|
||||
|
||||
json_object_put(jobj_msg);
|
||||
}
|
||||
|
||||
void handle_timeout(int sig)
|
||||
{
|
||||
_exit(-2);
|
||||
}
|
||||
|
||||
void setup_timeout(int timeout_ms)
|
||||
{
|
||||
int rc;
|
||||
struct itimerval itv;
|
||||
itv.it_interval.tv_sec = 0;
|
||||
itv.it_interval.tv_usec = 0;
|
||||
itv.it_value.tv_sec = 0;
|
||||
itv.it_value.tv_usec = timeout_ms * 1000;
|
||||
|
||||
// normalize the timer
|
||||
while(itv.it_value.tv_usec >= 1000000) {
|
||||
itv.it_value.tv_usec -= 1000000;
|
||||
itv.it_value.tv_sec += 1;
|
||||
}
|
||||
|
||||
rc = setitimer(ITIMER_REAL, &itv, NULL);
|
||||
if (rc < 0) {
|
||||
ERR_LOG("unable to set timeout");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
if (signal(SIGALRM, handle_timeout) == SIG_ERR)
|
||||
ERR_LOG("unable to set timeout handler, continuing anyway: %m");
|
||||
}
|
||||
|
||||
struct json_object *create_new_jobj_msg(int timeout_ms,
|
||||
const char *resource,
|
||||
const char *direction,
|
||||
int cpu,
|
||||
const char *online_cpus)
|
||||
{
|
||||
//validate values
|
||||
if (timeout_ms < TIMEOUT_OVERHEAD_MS) {
|
||||
printf("timeout %d too short\n", timeout_ms);
|
||||
goto invalid_values;
|
||||
}
|
||||
|
||||
if (strcmp(resource, "cpu")!=0) {
|
||||
printf("invalid resource %s\n", resource);
|
||||
goto invalid_values;
|
||||
}
|
||||
|
||||
struct json_object *jobj_online_cpus;
|
||||
if (!strcmp(direction, "up")) {
|
||||
jobj_online_cpus = json_tokener_parse(online_cpus);
|
||||
if (!json_object_is_type(jobj_online_cpus, json_type_array)) {
|
||||
printf("invalid online_cpus %s\n", online_cpus);
|
||||
goto invalid_values;
|
||||
}
|
||||
len_request_online_cpus = json_object_array_length(jobj_online_cpus);
|
||||
request_online_cpus = malloc(len_request_online_cpus*sizeof(int));
|
||||
int i;
|
||||
for (i=0; i< len_request_online_cpus; i++) {
|
||||
request_online_cpus[i] = json_object_get_int(json_object_array_get_idx(jobj_online_cpus, i));
|
||||
}
|
||||
|
||||
} else if (strcmp(direction, "down")!=0) {
|
||||
printf("invalid direction %s\n", direction);
|
||||
goto invalid_values;
|
||||
}
|
||||
|
||||
struct json_object *jobj_msg = json_object_new_object();
|
||||
if (jobj_msg == NULL) {
|
||||
printf("failed to allocate json object for msg\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
json_object_object_add(jobj_msg, VERSION, json_object_new_int(CUR_VERSION));
|
||||
json_object_object_add(jobj_msg, MSG_TYPE, json_object_new_string(MSG_TYPE_SCALE_REQUEST));
|
||||
json_object_object_add(jobj_msg, TIMEOUT_MS, json_object_new_int(timeout_ms - MIN_SCRIPT_TIMEOUT_MS));
|
||||
json_object_object_add(jobj_msg, RESOURCE, json_object_new_string(resource));
|
||||
json_object_object_add(jobj_msg, DIRECTION, json_object_new_string(direction));
|
||||
|
||||
if (!strcmp(direction, "up")) {
|
||||
json_object_object_add(jobj_msg, ONLINE_CPU, json_object_new_int(cpu));
|
||||
json_object_object_add(jobj_msg, ONLINE_CPUS, jobj_online_cpus);
|
||||
}
|
||||
|
||||
return jobj_msg;
|
||||
|
||||
invalid_values:
|
||||
usage();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int i;
|
||||
char *instance_name;
|
||||
|
||||
// msg values
|
||||
int cpu;
|
||||
const char *resource;
|
||||
const char *direction;
|
||||
const char *request_online_cpus_str = NULL;
|
||||
|
||||
for(i=1;i<argc;i++) {
|
||||
if (0==strcmp(argv[i], "--timeout")) {
|
||||
i++;
|
||||
if (i<argc) {
|
||||
timeout_ms = atoi(argv[i]);
|
||||
} else {
|
||||
printf("timeout option specified without timeout value\n");
|
||||
usage();
|
||||
}
|
||||
} else if (0==strcmp(argv[i], "--instance_name")) {
|
||||
i++;
|
||||
if (i<argc) {
|
||||
int len = strlen(argv[i]) + 1;
|
||||
if (len > INSTANCE_NAME_SIZE) {
|
||||
printf("instance name is too large\n");
|
||||
usage();
|
||||
} else
|
||||
instance_name = argv[i];
|
||||
}
|
||||
else {
|
||||
printf("instance_name option specified without name\n");
|
||||
usage();
|
||||
}
|
||||
} else if (0==strcmp(argv[i], "--cpu_add")) {
|
||||
i++;
|
||||
if (i<argc) {
|
||||
cpu = atoi(argv[i]);
|
||||
i++;
|
||||
if (i<argc) {
|
||||
request_online_cpus_str = argv[i];
|
||||
} else {
|
||||
printf("cpu_add option specified but missing online cpu range\n");
|
||||
usage();
|
||||
}
|
||||
} else {
|
||||
printf("cpu_add option specified but missing cpu\n");
|
||||
usage();
|
||||
}
|
||||
resource = "cpu";
|
||||
direction = "up";
|
||||
} else if (0==strcmp(argv[i], "--cpu_del")) {
|
||||
resource = "cpu";
|
||||
direction = "down";
|
||||
} else if (0==strcmp(argv[i], "--help")) {
|
||||
usage();
|
||||
} else {
|
||||
printf("Unknown argument %s\n", argv[i]);
|
||||
usage();
|
||||
}
|
||||
}
|
||||
|
||||
struct json_object *jobj_msg = create_new_jobj_msg(timeout_ms, resource, direction,
|
||||
cpu, request_online_cpus_str);
|
||||
|
||||
if (jobj_msg == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
const char *msg = json_object_to_json_string_ext(jobj_msg, JSON_C_TO_STRING_PLAIN);
|
||||
// save request data to compare with response
|
||||
request_cpu = cpu;
|
||||
|
||||
setup_timeout(timeout_ms);
|
||||
handle_message(msg, instance_name);
|
||||
|
||||
json_object_put(jobj_msg);
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
/**
|
||||
* Copyright (c) <2015-2016>, Wind River Systems, Inc.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1) Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2) Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* 3) Neither the name of Wind River Systems nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software without specific
|
||||
* prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <syslog.h>
|
||||
|
||||
#define CUR_VERSION 2
|
||||
|
||||
#define LOG_MSG_SIZE 100
|
||||
#define SCALE_AGENT_ADDR "cgcs.scale"
|
||||
#define ERRORSIZE 400
|
||||
|
||||
// keys for guest scaling messages
|
||||
#define VERSION "version"
|
||||
#define TIMEOUT_MS "timeout_ms"
|
||||
#define RESOURCE "resource"
|
||||
#define DIRECTION "direction"
|
||||
#define ONLINE_CPU "online_cpu"
|
||||
#define OFFLINE_CPU "offline_cpu"
|
||||
#define ONLINE_CPUS "online_cpus"
|
||||
#define RESULT "result"
|
||||
#define ERR_MSG "err_msg"
|
||||
#define MSG_TYPE "msg_type"
|
||||
#define LOG_MSG "log_msg" // for Nack
|
||||
|
||||
// message types for scaling messages
|
||||
#define MSG_TYPE_SCALE_REQUEST "scale_request"
|
||||
#define MSG_TYPE_NACK "nack"
|
||||
|
||||
char errorbuf[ERRORSIZE];
|
||||
|
||||
#define LOG(priority, format, ...) \
|
||||
syslog(priority, "%s(%d): " format, __FILE__, __LINE__, ##__VA_ARGS__)
|
||||
|
||||
#define ERR_LOG(format, ...) \
|
||||
do { \
|
||||
LOG(LOG_DAEMON|LOG_ERR, format, ##__VA_ARGS__); \
|
||||
fprintf(stderr, format, ##__VA_ARGS__); \
|
||||
snprintf(errorbuf, sizeof(errorbuf)-1, format, ##__VA_ARGS__); \
|
||||
} while (0)
|
||||
|
||||
#define INFO_LOG(format, ...) \
|
||||
do { \
|
||||
LOG(LOG_DAEMON|LOG_INFO, format, ##__VA_ARGS__); \
|
||||
} while (0)
|
||||
|
||||
|
||||
struct online_cpus {
|
||||
int numcpus;
|
||||
char status[];
|
||||
};
|
||||
|
||||
struct online_cpus *range_to_array(const char *range);
|
||||
struct json_object *new_json_obj_from_array (struct online_cpus *cpuarray);
|
||||
void print_array(char *buf, int *array, int len);
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
# Ignore everything in this directory
|
||||
*
|
||||
# Except this file
|
||||
!.gitignore
|
||||
@@ -0,0 +1,150 @@
|
||||
/**
|
||||
* Copyright (c) <2013-2016>, Wind River Systems, Inc.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1) Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2) Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* 3) Neither the name of Wind River Systems nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software without specific
|
||||
* prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <json-c/json.h>
|
||||
#include "misc.h"
|
||||
|
||||
|
||||
/* Print a range of numbers in a consistent way. */
|
||||
char print_range(int start, int end, char *str)
|
||||
{
|
||||
int len;
|
||||
if (start == end)
|
||||
len = sprintf(str, "%d,", start);
|
||||
else
|
||||
len = sprintf(str, "%d-%d,", start, end);
|
||||
return len;
|
||||
}
|
||||
|
||||
void print_array(char *buf, int *array, int len) {
|
||||
int i;
|
||||
for(i = 0; i < len; i++) {
|
||||
sprintf(buf+strlen(buf),"%d,", array[i]);
|
||||
}
|
||||
// remove the last comma
|
||||
buf[strlen(buf)-1]='\0';
|
||||
}
|
||||
|
||||
#define BUFLEN 1024
|
||||
|
||||
/* Takes as input a string representation of online cpus of the form
|
||||
* "0,1,3-5", and allocates and returns a struct representing whether
|
||||
* each given cpu is online.
|
||||
*/
|
||||
struct online_cpus *range_to_array(const char *range)
|
||||
{
|
||||
struct online_cpus *cpuarray = (struct online_cpus *) malloc(BUFLEN);
|
||||
int start, end;
|
||||
int inrange = 0;
|
||||
char *token, *tmp;
|
||||
int done = 0;
|
||||
tmp = strdup(range);
|
||||
strcpy(tmp, range);
|
||||
token = tmp;
|
||||
|
||||
if (*tmp == '\0') {
|
||||
/* empty string, no online cpus */
|
||||
cpuarray->numcpus = 0;
|
||||
return cpuarray;
|
||||
}
|
||||
|
||||
while (1) {
|
||||
tmp++;
|
||||
if (*tmp == '\0')
|
||||
done = 1;
|
||||
if (done || (*tmp == ',')) {
|
||||
/* expect single value or ending a range */
|
||||
if (!token) {
|
||||
ERR_LOG("format error, missing token, unable to parse range\n");
|
||||
goto error;
|
||||
}
|
||||
*tmp = '\0';
|
||||
end = atoi(token);
|
||||
token = 0;
|
||||
if (inrange) {
|
||||
int i;
|
||||
for (i=start; i<= end; i++)
|
||||
cpuarray->status[i] = 1;
|
||||
inrange = 0;
|
||||
} else {
|
||||
cpuarray->status[end] = 1;
|
||||
}
|
||||
} else if (*tmp == '-') {
|
||||
if (inrange) {
|
||||
ERR_LOG("format error, unable to parse range\n");
|
||||
goto error;
|
||||
}
|
||||
if (!token) {
|
||||
ERR_LOG("format error, missing token, unable to parse range\n");
|
||||
goto error;
|
||||
}
|
||||
*tmp = '\0';
|
||||
start = atoi(token);
|
||||
token = 0;
|
||||
inrange = 1;
|
||||
} else {
|
||||
/* expect a numerical value */
|
||||
if ((*tmp < '0') || (*tmp > '9')) {
|
||||
ERR_LOG("format error, expected a numerical value, unable to parse range\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (!token)
|
||||
token = tmp;
|
||||
}
|
||||
if (done)
|
||||
break;
|
||||
}
|
||||
cpuarray->numcpus = end+1;
|
||||
return cpuarray;
|
||||
error:
|
||||
free(cpuarray);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
struct json_object *new_json_obj_from_array (struct online_cpus *cpuarray)
|
||||
{
|
||||
int i;
|
||||
|
||||
struct json_object *jobj_array = json_object_new_array();
|
||||
if (jobj_array == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i=0;i<cpuarray->numcpus;i++) {
|
||||
if (cpuarray->status[i]) {
|
||||
json_object_array_add(jobj_array, json_object_new_int(i));
|
||||
}
|
||||
}
|
||||
return jobj_array;
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
#
|
||||
# Copyright(c) 2013-2016, Wind River Systems, Inc.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in
|
||||
# the documentation and/or other materials provided with the
|
||||
# distribution.
|
||||
# * Neither the name of Wind River Systems nor the names of its
|
||||
# contributors may be used to endorse or promote products derived
|
||||
# from this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <misc.h>
|
||||
|
||||
void printstruct(struct online_cpus *cpuarray)
|
||||
{
|
||||
int i;
|
||||
printf("num cpus: %d\n", cpuarray->numcpus);
|
||||
for (i=0;i<cpuarray->numcpus;i++)
|
||||
printf("%d: %d\n", i, cpuarray->status[i]);
|
||||
}
|
||||
|
||||
|
||||
struct online_cpus cpus = {15, {1,0,0,0,0,0,1,1,1,0,0,0,1,1,1}};
|
||||
int main()
|
||||
{
|
||||
char *str, *str2;
|
||||
struct online_cpus *newcpus;
|
||||
printf("initial: \n");
|
||||
printstruct(&cpus);
|
||||
printf("string:\n");
|
||||
str = "0,6-8,12-14";
|
||||
newcpus = range_to_array(str);
|
||||
printf("fromstring: \n");
|
||||
printstruct(newcpus);
|
||||
newcpus = range_to_array("");
|
||||
printf("empty: \n");
|
||||
printstruct(newcpus);
|
||||
newcpus = range_to_array("0--2");
|
||||
newcpus = range_to_array("0-1-2");
|
||||
newcpus = range_to_array("0,,2");
|
||||
newcpus = range_to_array("0,-2");
|
||||
newcpus = range_to_array("1,2-a");
|
||||
|
||||
return 0;
|
||||
}
|
||||
+107
@@ -0,0 +1,107 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Copyright(c) 2013-2016, Wind River Systems, Inc.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in
|
||||
# the documentation and/or other materials provided with the
|
||||
# distribution.
|
||||
# * Neither the name of Wind River Systems nor the names of its
|
||||
# contributors may be used to endorse or promote products derived
|
||||
# from this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
# This is a basic sample script showing what the script needs to be able to do.
|
||||
# The script can be edited as needed or replaced by a script or binary that
|
||||
# works in the same way, or can be deleted entirely if the default behaviour
|
||||
# of offlining the highest-numbered CPU is satisfactory and you don't care
|
||||
# about logging scaling events.
|
||||
#
|
||||
# We expect to be called in one of the following ways:
|
||||
#
|
||||
# "--cpu_add <cpu> <new cpu range>"
|
||||
#
|
||||
# This indicates that "cpu" has been set online, and we can now make use of it.
|
||||
# Do whatever is necessary to start using it, then return 0.
|
||||
#
|
||||
#
|
||||
# "--cpu_del"
|
||||
# In this case we pick an online cpu to offline, and do whatever we need to in
|
||||
# order to stop using it, and return the cpu number. Note that CPU 0 must
|
||||
# always remain online.
|
||||
|
||||
info_log()
|
||||
{
|
||||
logger -p daemon.info -t $0 "$*"
|
||||
echo $*
|
||||
}
|
||||
|
||||
err_log()
|
||||
{
|
||||
logger -p daemon.err -t $0 "$*"
|
||||
echo $*
|
||||
}
|
||||
|
||||
usage()
|
||||
{
|
||||
err_log "usage: $0 {--cpu_del | --cpu_add <cpu> <new cpu range>}"
|
||||
exit -1
|
||||
}
|
||||
|
||||
cpu_scale_up ()
|
||||
{
|
||||
CPU_NUM=$1
|
||||
CPU_ONLINE_RANGE=$2
|
||||
info_log "cpu add notification, cpu: ${CPU_NUM}"
|
||||
info_log "cpu_online_range: ${CPU_ONLINE_RANGE}"
|
||||
}
|
||||
|
||||
cpu_scale_down ()
|
||||
{
|
||||
# Make sure host & guest views of offline cpus are consistent
|
||||
/usr/sbin/offline_cpus
|
||||
|
||||
info_log "cpu del request"
|
||||
#pick the highest online cpu
|
||||
CPUS_ONLINE=`cat /sys/devices/system/cpu/online`
|
||||
CPU_NUM=${CPUS_ONLINE##*[,-]}
|
||||
|
||||
info_log "selected cpu ${CPU_NUM} to offline"
|
||||
return $CPU_NUM
|
||||
}
|
||||
|
||||
if [ $# -lt 1 ]
|
||||
then
|
||||
usage
|
||||
elif [ $1 = "--cpu_add" ]
|
||||
then
|
||||
if [ $# = 3 ]
|
||||
then
|
||||
cpu_scale_up $2 $3
|
||||
else
|
||||
err_log "--cpu_add option called with $# args, expected 3"
|
||||
usage
|
||||
fi
|
||||
elif [ $1 = "--cpu_del" ]
|
||||
then
|
||||
cpu_scale_down
|
||||
else
|
||||
usage
|
||||
fi
|
||||
@@ -0,0 +1,13 @@
|
||||
[Unit]
|
||||
Description=Guest Scale Agent
|
||||
After=cloud-init.service
|
||||
Wants=guest-agent.service
|
||||
|
||||
[Service]
|
||||
ExecStart=/usr/sbin/guest_scale_agent
|
||||
Type=simple
|
||||
Restart=always
|
||||
RestartSec=0
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
@@ -0,0 +1,64 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright(c) 2013-2016, Wind River Systems, Inc.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in
|
||||
# the documentation and/or other materials provided with the
|
||||
# distribution.
|
||||
# * Neither the name of Wind River Systems nor the names of its
|
||||
# contributors may be used to endorse or promote products derived
|
||||
# from this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
|
||||
DAEMON=/usr/sbin/offline_cpus
|
||||
NAME=offline_cpus
|
||||
DESC="offline cpus marked offline by hypervisor"
|
||||
ARGS=
|
||||
|
||||
test -f $DAEMON || exit 0
|
||||
|
||||
case "$1" in
|
||||
start)
|
||||
echo -n "running $DESC: $NAME... "
|
||||
$DAEMON $ARGS
|
||||
echo "done."
|
||||
;;
|
||||
stop)
|
||||
echo -n "stopping $DESC: $NAME... "
|
||||
echo "done."
|
||||
;;
|
||||
status)
|
||||
echo -n "$NAME is not running"
|
||||
;;
|
||||
restart)
|
||||
echo "restarting $DESC: $NAME... "
|
||||
$0 stop
|
||||
$0 start
|
||||
echo "done."
|
||||
;;
|
||||
*)
|
||||
echo "Usage: $0 {start|stop|status|restart}"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
exit 0
|
||||
@@ -0,0 +1,12 @@
|
||||
[Unit]
|
||||
Description=Titanium Cloud agent and helper app to scale VMs up/down
|
||||
After=cloud-init.service
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
RemainAfterExit=yes
|
||||
ExecStart=/etc/init.d/offline_cpus start
|
||||
ExecStop=/etc/init.d/offline_cpus stop
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
@@ -0,0 +1,54 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Copyright(c) 2013-2016, Wind River Systems, Inc.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in
|
||||
# the documentation and/or other materials provided with the
|
||||
# distribution.
|
||||
# * Neither the name of Wind River Systems nor the names of its
|
||||
# contributors may be used to endorse or promote products derived
|
||||
# from this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
|
||||
# Query the metadata server for the set of cpus that are supposed to be offline
|
||||
# It will be in the form "set([])" for the empty set, and "set([1, 2, 3])" for the
|
||||
# non-empty set.
|
||||
CPUSET_OFFLINE=`wget -t 3 -T 5 -qO - http://169.254.169.254/latest/meta-data/offline_cpuset`
|
||||
RC=$?
|
||||
if [ $RC -ne 0 ]
|
||||
then
|
||||
logger -p daemon.err "${0}: unable to obtain "offline_cpuset" value. rc: ${RC}"
|
||||
exit -1
|
||||
fi
|
||||
|
||||
OFFLINE_CPUS=`echo ${CPUSET_OFFLINE}|grep -oE [0-9]+`
|
||||
for CPU in $OFFLINE_CPUS
|
||||
do
|
||||
# Offline this cpu to match the underlying virtual machine.
|
||||
echo 0 > /sys/devices/system/cpu/cpu${CPU}/online
|
||||
RC=$?
|
||||
if [ $RC -ne 0 ]
|
||||
then
|
||||
logger -p daemon.err "${0}: unable to offline cpu ${CPU}. rc: ${RC}"
|
||||
exit -1
|
||||
fi
|
||||
done
|
||||
@@ -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,12 @@
|
||||
Metadata-Version: 1.1
|
||||
Name: guest-client
|
||||
Version: 3.0.1
|
||||
Summary: Titanium Cloud Platform Guest-Client Heartbeat Package
|
||||
Home-page:
|
||||
Author: Windriver
|
||||
Author-email: info@windriver.com
|
||||
License: Apache-2.0
|
||||
|
||||
Description: Guest-Client with heartbeat functionality.
|
||||
|
||||
Platform: UNKNOWN
|
||||
@@ -0,0 +1,3 @@
|
||||
SRC_DIR=$CGCS_BASE/mwa-thales/guest-client
|
||||
COPY_LIST="$SRC_DIR/*"
|
||||
TIS_PATCH_VER=5
|
||||
@@ -0,0 +1,114 @@
|
||||
Summary: Guest-Client
|
||||
Name: guest-client
|
||||
Version: 3.0.1
|
||||
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
|
||||
#Source1: guest_heartbeat_msg_defs.h
|
||||
|
||||
%define cgcs_sdk_deploy_dir /opt/deploy/cgcs_sdk
|
||||
|
||||
%bcond_without systemd
|
||||
|
||||
%if %{with systemd}
|
||||
Requires(post): systemd
|
||||
Requires(preun): systemd
|
||||
Requires(postun): systemd
|
||||
BuildRequires: systemd
|
||||
%endif
|
||||
|
||||
%package -n guest-client-devel
|
||||
Summary: Guest-Client - Development files
|
||||
Group: devel
|
||||
Provides: guest-client-dev(x86_64) = 3.0.1-r1.0
|
||||
|
||||
%package -n %{name}-cgts-sdk
|
||||
Summary: Guest-Client - SDK files
|
||||
Group: devel
|
||||
BuildRequires: json-c-devel
|
||||
|
||||
%description
|
||||
Guest-Client with heartbeat functionality.
|
||||
|
||||
%description -n guest-client-devel
|
||||
Guest-Client with heartbeat functionality. This package contains symbolic
|
||||
links, header files, and related items necessary for software development.
|
||||
|
||||
%description -n %{name}-cgts-sdk
|
||||
Guest-Client SDK files
|
||||
|
||||
%prep
|
||||
%setup
|
||||
#%build -C guest-client-3.0.1/guest_client/src/heartbeat
|
||||
#tar czf %{name}-%{version}.tgz %{name}-%{version}
|
||||
#find . -name "*.tgz"
|
||||
#echo `pwd`
|
||||
# Build for guest-client package
|
||||
cd guest-client-3.0.1
|
||||
make clean
|
||||
make build sysconfdir=%{_sysconfdir}
|
||||
make sample
|
||||
make tar ARCHIVE_NAME=wrs-guest-heartbeat-%{version}
|
||||
find build
|
||||
cd ..
|
||||
|
||||
# Install for guest-client package
|
||||
%install
|
||||
install -m 750 -d %{buildroot}/usr
|
||||
install -m 750 -d %{buildroot}%{_includedir}
|
||||
install -m 750 -d %{buildroot}%{_includedir}/guest-client
|
||||
install -m 640 -p -D %{name}-%{version}/guest_client/src/heartbeat/guest_heartbeat_msg_defs.h %{buildroot}%{_includedir}/guest-client/guest_heartbeat_msg_defs.h
|
||||
install -d %{buildroot}%{cgcs_sdk_deploy_dir}
|
||||
install -m 640 %{name}-%{version}/build/wrs-guest-heartbeat-%{version}.tgz %{buildroot}%{cgcs_sdk_deploy_dir}
|
||||
%if %{with systemd}
|
||||
install -m 644 -p -D %{name}-%{version}/guest_client/scripts/guest-client.service %{buildroot}%{_unitdir}/guest-client.service
|
||||
install -m 744 -p -D %{name}-%{version}/guest_client/scripts/guest-client.systemd %{buildroot}%{_sysconfdir}/guest-client/guest-client.systemd
|
||||
%endif
|
||||
install -m 750 -d %{buildroot}%{_sysconfdir}/guest-client/heartbeat
|
||||
install -m 755 -p -D %{name}-%{version}/guest_client/scripts/guest_heartbeat.conf %{buildroot}%{_sysconfdir}/guest-client/heartbeat/guest_heartbeat.conf
|
||||
install -m 755 -p -D %{name}-%{version}/guest_client/scripts/sample_event_handling_script %{buildroot}%{_sysconfdir}/guest-client/heartbeat/sample_event_handling_script
|
||||
install -m 755 -p -D %{name}-%{version}/guest_client/scripts/sample_health_check_script %{buildroot}%{_sysconfdir}/guest-client/heartbeat/sample_health_check_script
|
||||
install -m 640 -p -D %{name}-%{version}/build/guest-client %{buildroot}/usr/local/bin/guest-client
|
||||
install -m 640 -p -D %{name}-%{version}/build/libguest_common_api.so.%{version} %{buildroot}/usr/local/lib/libguest_common_api.so.%{version}
|
||||
install -m 640 -p -D %{name}-%{version}/build/libguest_heartbeat_api.so.%{version} %{buildroot}/usr/local/lib/libguest_heartbeat_api.so.%{version}
|
||||
|
||||
%files
|
||||
%defattr(755,root,root,-)
|
||||
%{_sysconfdir}/guest-client/heartbeat/guest_heartbeat.conf
|
||||
%{_sysconfdir}/guest-client/heartbeat/sample_event_handling_script
|
||||
%{_sysconfdir}/guest-client/heartbeat/sample_health_check_script
|
||||
%defattr(644,root,root,-)
|
||||
/usr/local/lib/libguest_common_api.so.%{version}
|
||||
/usr/local/lib/libguest_heartbeat_api.so.%{version}
|
||||
%attr(744,-,-) /usr/local/bin/guest-client
|
||||
%if %{with systemd}
|
||||
%{_unitdir}/guest-client.service
|
||||
%attr(744,-,-) %{_sysconfdir}/guest-client/guest-client.systemd
|
||||
%endif
|
||||
|
||||
%preun
|
||||
%if %{with systemd}
|
||||
/usr/bin/systemctl stop guest-client >/dev/null 2>&1
|
||||
%systemd_preun guest-client.service
|
||||
systemctl reload
|
||||
%endif
|
||||
|
||||
%post
|
||||
%if %{with systemd}
|
||||
%systemd_post guest-client.service
|
||||
systemctl reload
|
||||
/usr/bin/systemctl enable guest-client >/dev/null 2>&1
|
||||
%endif
|
||||
|
||||
%files -n guest-client-devel
|
||||
|
||||
%defattr(644,root,root,-)
|
||||
|
||||
/usr/include/guest-client/guest_heartbeat_msg_defs.h
|
||||
|
||||
%files -n %{name}-cgts-sdk
|
||||
%{cgcs_sdk_deploy_dir}/wrs-guest-heartbeat-%{version}.tgz
|
||||
@@ -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.
|
||||
Executable
+119
@@ -0,0 +1,119 @@
|
||||
#
|
||||
# Copyright(c) 2013-2016, Wind River Systems, Inc.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in
|
||||
# the documentation and/or other materials provided with the
|
||||
# distribution.
|
||||
# * Neither the name of Wind River Systems nor the names of its
|
||||
# contributors may be used to endorse or promote products derived
|
||||
# from this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
SHELL = /bin/sh
|
||||
|
||||
## Configuration Directory Variables
|
||||
prefix := /usr/local
|
||||
exec_prefix := $(prefix)
|
||||
sysconfdir := $(prefix)/etc
|
||||
includedir := $(prefix)/include
|
||||
libdir := $(exec_prefix)/lib
|
||||
bindir := $(exec_prefix)/bin
|
||||
|
||||
MAKEFILE_PATH := $(abspath $(lastword $(MAKEFILE_LIST)))
|
||||
CURRENT_DIR := $(patsubst %/,%,$(dir $(MAKEFILE_PATH)))
|
||||
PARENT_DIR := $(patsubst %/,%,$(dir $(CURRENT_DIR)))
|
||||
BUILD_DIR := $(CURRENT_DIR)/build
|
||||
PACKAGE_DIR := $(BUILD_DIR)/package
|
||||
PACKAGE_ROOT_DIR := $(PACKAGE_DIR)/rootdir
|
||||
|
||||
ARCHIVE_NAME := wrs-guest-client-3.0.1
|
||||
ARCHIVE_PKG_NAME := wrs-guest-client-3.0.1_pkg
|
||||
|
||||
INIT_TYPE := sysv
|
||||
|
||||
.PHONY: all build sample clean distclean tar package install uninstall
|
||||
|
||||
all: build
|
||||
|
||||
build:
|
||||
mkdir -p --mode 755 $(BUILD_DIR)
|
||||
@(cd guest_client_api; make --no-print-directory build \
|
||||
sysconfdir=$(sysconfdir) BUILD_DIR=$(BUILD_DIR))
|
||||
@(cd guest_client; make --no-print-directory build \
|
||||
sysconfdir=$(sysconfdir) BUILD_DIR=$(BUILD_DIR))
|
||||
|
||||
tar:
|
||||
@(mkdir -p --mode 755 $(BUILD_DIR))
|
||||
@(ln -sf $(CURRENT_DIR) $(BUILD_DIR)/$(ARCHIVE_NAME))
|
||||
@(cd $(BUILD_DIR); tar -pczf $(ARCHIVE_NAME).tgz \
|
||||
$(ARCHIVE_NAME)/Makefile \
|
||||
$(ARCHIVE_NAME)/LICENSE \
|
||||
$(ARCHIVE_NAME)/README \
|
||||
$(ARCHIVE_NAME)/README.build \
|
||||
$(ARCHIVE_NAME)/README.usage \
|
||||
$(ARCHIVE_NAME)/TiS-Guest-Heartbeat-Service.pdf \
|
||||
$(ARCHIVE_NAME)/packaging \
|
||||
$(ARCHIVE_NAME)/include \
|
||||
$(ARCHIVE_NAME)/guest_client \
|
||||
$(ARCHIVE_NAME)/guest_client_api \
|
||||
--exclude $(ARCHIVE_NAME)/guest_client/build \
|
||||
--exclude $(ARCHIVE_NAME)/guest_client/src/test \
|
||||
--exclude $(ARCHIVE_NAME)/guest_client_api/build \
|
||||
--directory $(BUILD_DIR))
|
||||
|
||||
sample:
|
||||
mkdir -p --mode 755 $(BUILD_DIR)
|
||||
@(cd guest_client_api; make --no-print-directory sample \
|
||||
sysconfdir=$(sysconfdir) BUILD_DIR=$(BUILD_DIR))
|
||||
@(cd guest_client; make --no-print-directory sample \
|
||||
sysconfdir=$(sysconfdir) BUILD_DIR=$(BUILD_DIR))
|
||||
|
||||
clean:
|
||||
@-(cd guest_client_api; make --no-print-directory clean BUILD_DIR=$(BUILD_DIR))
|
||||
@-(cd guest_client; make --no-print-directory clean BUILD_DIR=$(BUILD_DIR))
|
||||
|
||||
distclean: clean
|
||||
|
||||
package:
|
||||
@(mkdir -p --mode 755 $(PACKAGE_DIR))
|
||||
@(mkdir -p --mode 755 $(PACKAGE_ROOT_DIR))
|
||||
@(ln -sf $(PACKAGE_DIR) $(BUILD_DIR)/$(ARCHIVE_PKG_NAME))
|
||||
@(echo "Packaging guest-client.pkg in $(PACKAGE_DIR)")
|
||||
@(cp $(CURRENT_DIR)/packaging/guest-client.pkg $(PACKAGE_DIR)/guest-client.pkg)
|
||||
@(chmod 755 $(PACKAGE_DIR)/guest-client.pkg)
|
||||
@-(cd guest_client_api; make --no-print-directory package BUILD_DIR=$(BUILD_DIR) \
|
||||
PACKAGE_DIR=$(PACKAGE_DIR) prefix=$(prefix) exec_prefix=$(exec_prefix) \
|
||||
sysconfdir=$(sysconfdir) includedir=$(includedir) libdir=$(libdir) \
|
||||
bindir=$(bindir))
|
||||
@-(cd guest_client; make --no-print-directory package BUILD_DIR=$(BUILD_DIR) \
|
||||
PACKAGE_DIR=$(PACKAGE_DIR) prefix=$(prefix) exec_prefix=$(exec_prefix) \
|
||||
sysconfdir=$(sysconfdir) includedir=$(includedir) libdir=$(libdir) \
|
||||
bindir=$(bindir))
|
||||
@(cd $(BUILD_DIR); tar -pczf $(ARCHIVE_PKG_NAME).tgz \
|
||||
$(ARCHIVE_PKG_NAME)/* --directory $(PACKAGE_DIR))
|
||||
|
||||
install: package
|
||||
@(echo "Installing ...")
|
||||
@(cd $(PACKAGE_DIR); ./guest-client.pkg install $(INIT_TYPE) $(DESTDIR))
|
||||
|
||||
uninstall: package
|
||||
@(echo "Uninstalling ...")
|
||||
@(cd $(PACKAGE_DIR); ./guest-client.pkg uninstall $(INIT_TYPE) $(DESTDIR))
|
||||
Executable
+72
@@ -0,0 +1,72 @@
|
||||
Copyright(c) 2013-2017, Wind River Systems, Inc.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
* Neither the name of Wind River Systems nor the names of its
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
-----------------------------------------------------------------------
|
||||
|
||||
TITANIUM CLOUD - GUEST HEARTBEAT SDK
|
||||
===========================================
|
||||
|
||||
DESCRIPTION
|
||||
===========
|
||||
Titanium Cloud Guest-Client provides a heartbeat service to monitor the
|
||||
health of guest application(s) within a VM running under WindRiver's
|
||||
Titanium Cloud. Loss of heartbeat will result in a corrective action
|
||||
being taken against the VM. The heartbeat interval and corrective action
|
||||
is specified by the VM.
|
||||
|
||||
Titanium Cloud Guest-Client also provides guest application(s) within
|
||||
a VM running under WindRiver's Titanium Cloud, the ability to receive
|
||||
notification of and vote to accept or reject actions about to be performed
|
||||
against the VM. On notifications, the guest application within the VM can
|
||||
take this opportunity to cleanly shut down or transfer its service to a
|
||||
peer VM.
|
||||
|
||||
+-------- Virtual Machine ------------------------+
|
||||
| |
|
||||
| VM-Health-Check-Script |
|
||||
| / |
|
||||
| / Guest-Application-1 |
|
||||
Titanium Cloud <----> TiS-Guest-Client <-----> ... |
|
||||
| \ Guest-Application-8 |
|
||||
| \ |
|
||||
| VM-Event-Script |
|
||||
| |
|
||||
+-------------------------------------------------+
|
||||
|
||||
See also:
|
||||
|
||||
README.build - building and installing.
|
||||
|
||||
README.usage - configuring and using the heartbeat, notification
|
||||
and voting functionality.
|
||||
|
||||
|
||||
DELIVERY
|
||||
========
|
||||
Titanium Cloud Guest-Client is delivered as source in a compressed
|
||||
tarball, wrs-guest-client-v3.0.0.tgz, such that it can be compiled for
|
||||
the applicable VM Linux distribution.
|
||||
Executable
+291
@@ -0,0 +1,291 @@
|
||||
Copyright(c) 2013-2017, Wind River Systems, Inc.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
* Neither the name of Wind River Systems nor the names of its
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
-----------------------------------------------------------------------
|
||||
|
||||
This file contains instructions for building and installing the Titanium Cloud
|
||||
Guest-Client.
|
||||
|
||||
|
||||
REQUIREMENTS
|
||||
============
|
||||
The Guest-Client uses the SIGIO functionality of the virtio-serial device
|
||||
to track host connection up, down and port unplug events. This functionality
|
||||
requires a kernel version equal to or greater than 2.6.37.
|
||||
|
||||
Compilation:
|
||||
Linux OS ## Same architecture as the VM.
|
||||
|
||||
gnu make
|
||||
gcc compiler
|
||||
|
||||
development libraries and headers for:
|
||||
libc ## C library
|
||||
rt ## Real-Time library
|
||||
json-c ## JSON-C library
|
||||
|
||||
VM Runtime:
|
||||
Linux OS
|
||||
|
||||
runtime libraries:
|
||||
libc ## C library
|
||||
rt ## Real-Time library
|
||||
json-c ## JSON-C library
|
||||
|
||||
|
||||
COMPILE
|
||||
=======
|
||||
Extract the tarball contents ...
|
||||
|
||||
tar -xvf wrs-guest-heartbeat-v3.0.0.tgz
|
||||
|
||||
To compile, simply run ...
|
||||
|
||||
cd wrs-guest-heartbeat-3.0.0
|
||||
make
|
||||
|
||||
This will create a build output directory called "build" in the
|
||||
wrs-guest-heartbeat-3.0.0 directory. The build output directory
|
||||
contains the following relevant files:
|
||||
|
||||
libguest_common_api.so.3.0.0
|
||||
libguest_heartbeat_api.so.3.0.0
|
||||
guest-client
|
||||
|
||||
The libguest_common_api library contains all the common code for
|
||||
the Guest-Client API libraries.
|
||||
|
||||
The libguest_heartbeat_api library contains the heartbeat, voting,
|
||||
and notification functionality to interact with the Guest-Client.
|
||||
A guest application wanting to use this functionality needs to link
|
||||
in the libguest_common_api and libguest_heartbeat_api libraries.
|
||||
|
||||
The guest-client executable is the Guest-Client daemon that heartbeats
|
||||
guest applications, and orchestrates votes on and notifications of
|
||||
pending actions against the VM. The Guest-Client reports the health,
|
||||
notification and voting results of guest application(s) to the
|
||||
Titanium Cloud.
|
||||
|
||||
The following variables are available to change the build output
|
||||
directory and where the system configuration files will be located:
|
||||
|
||||
BUILD_DIR - used to change the build output directory, defaults
|
||||
to the wrs-guest-heartbeat-3.0.0/build directory.
|
||||
|
||||
prefix - used to construct other variables below, defaults to
|
||||
the /usr/local directory.
|
||||
|
||||
sysconfdir - directory for configuration files, set to
|
||||
$(prefix)/etc
|
||||
|
||||
Note: all directory variables must specify an absolute path.
|
||||
|
||||
Usage: make <variable-name>=<variable-value>
|
||||
|
||||
To compile the sample-guest-app, simply run ...
|
||||
|
||||
cd wrs-guest-heartbeat-3.0.0
|
||||
make sample
|
||||
|
||||
The sample-guest-app executable is for demonstration purposes only.
|
||||
It demonstrates how a guest application can use the guest heartbeat
|
||||
library, libguest_heartbeat_api, to interact with the Guest-Client.
|
||||
|
||||
To compile with a different compiler, simply run ...
|
||||
|
||||
cd wrs-guest-heartbeat-3.0.0
|
||||
make CC=/x86_64/buildroot/host/usr/bin/x86_64-buildroot-linux-uclibc-cc
|
||||
|
||||
|
||||
PACKAGE
|
||||
=======
|
||||
To build a tar package for installation, simply run ...
|
||||
|
||||
cd wrs-guest-heartbeat-3.0.0
|
||||
make package
|
||||
|
||||
This will create a tar file called wrs-guest-heartbeat-3.0.0_pkg.tgz
|
||||
in the wrs-guest-heartbeat-3.0.0 build directory.
|
||||
|
||||
If you changed the build output directory during compile, the BUILD_DIR
|
||||
variable will have to be specified on the make package. Also if you
|
||||
specified a different system configuration directory, the sysconfdir
|
||||
variable, during compile, it will also have to be specified on the
|
||||
make package.
|
||||
|
||||
The following package configuration variables are available to customize
|
||||
the package for installation:
|
||||
|
||||
prefix - used to construct other variables below, defaults to
|
||||
the /usr/local directory.
|
||||
|
||||
exec_prefix - used to construct other executable variables, set to
|
||||
the 'prefix' variable.
|
||||
|
||||
sysconfdir - directory for configuration files, set to
|
||||
$(prefix)/etc
|
||||
|
||||
includedir - directory for installing header files, set to
|
||||
$(prefix)/include
|
||||
|
||||
libdir - directory for installing libraries, set to
|
||||
$(exec_prefix)/lib
|
||||
|
||||
bindir - directory for installing executable programs, set to
|
||||
$(exec_prefix)/bin
|
||||
|
||||
Note: all directory variables must specify an absolute path.
|
||||
|
||||
Usage: make package <variable-name>=<variable-value> ...
|
||||
|
||||
|
||||
INSTALL
|
||||
=======
|
||||
To install from source directories, simply run ...
|
||||
|
||||
cd wrs-guest-heartbeat-3.0.0
|
||||
make install
|
||||
|
||||
This will install the default configuration file, include files,
|
||||
compiled libraries and executable into the following directories:
|
||||
|
||||
guest_heartbeat.conf --> /usr/local/etc/guest-client/heartbeat
|
||||
guest_api_types.h --> /usr/local/include
|
||||
guest_heartbeat_api.h --> /usr/local/include
|
||||
libguest_common_api.so.3.0.0 --> /usr/local/lib
|
||||
libguest_heartbeat_api.so.3.0.0 --> /usr/local/lib
|
||||
guest-client --> /usr/local/bin
|
||||
|
||||
If you changed the build output directory during compile, the BUILD_DIR
|
||||
variable will have to be specified on the make install. Also if you
|
||||
specified a different system configuration directory, the sysconfdir
|
||||
variable, during compile, it will also have to be specified on the
|
||||
make install.
|
||||
|
||||
The following install configuration variables are available to customize
|
||||
installation:
|
||||
|
||||
INIT_TYPE - the type of initialization the OS is using, one of
|
||||
( systemd or sysv ). Default to sysv.
|
||||
|
||||
DESTDIR - prepended to each install target file, used to provide
|
||||
an alternate environment to install in (i.e. support
|
||||
for staged installs).
|
||||
|
||||
prefix - used to construct other variables below, defaults to
|
||||
the /usr/local directory.
|
||||
|
||||
exec_prefix - used to construct other executable variables, set to
|
||||
the 'prefix' variable.
|
||||
|
||||
sysconfdir - directory for configuration files, set to
|
||||
$(prefix)/etc
|
||||
|
||||
includedir - directory for installing header files, set to
|
||||
$(prefix)/include
|
||||
|
||||
libdir - directory for installing libraries, set to
|
||||
$(exec_prefix)/lib
|
||||
|
||||
bindir - directory for installing executable programs, set to
|
||||
$(exec_prefix)/bin
|
||||
|
||||
Note: all directory variables must specify an absolute path.
|
||||
|
||||
Usage: make <install | uninstall> <variable-name>=<variable-value> ...
|
||||
|
||||
|
||||
|
||||
To install from a tar package file, simply run ...
|
||||
|
||||
tar -xvf wrs-guest-heartbeat-v3.0.0_pkg.tgz
|
||||
|
||||
cd wrs-guest-heartbeat-v3.0.0_pkg
|
||||
guest-client.pkg install
|
||||
|
||||
This will install the default configuration file, include files,
|
||||
compiled libraries and executable into the following directories:
|
||||
|
||||
guest_heartbeat.conf --> /usr/local/etc/guest-client/heartbeat
|
||||
guest_api_types.h --> /usr/local/include
|
||||
guest_heartbeat_api.h --> /usr/local/include
|
||||
libguest_common_api.so.3.0.0 --> /usr/local/lib
|
||||
libguest_heartbeat_api.so.3.0.0 --> /usr/local/lib
|
||||
guest-client --> /usr/local/bin
|
||||
|
||||
To uninstall: guest-client.pkg uninstall
|
||||
|
||||
The following install configuration variables can be provided to
|
||||
customize installation:
|
||||
|
||||
INIT_TYPE - the type of initialization the OS is using, one of
|
||||
( systemd, sysv ). Optional parameter, defaults to
|
||||
sysv.
|
||||
|
||||
DESTDIR - prepended to each install target file, used to provide
|
||||
an alternate environment to install in (i.e. support
|
||||
for staged installs). Optional parameter.
|
||||
|
||||
Note: all directory variables must specify an absolute path.
|
||||
|
||||
guest-client.pkg <install | uninstall> <systemd | sysv> [DESTDIR]
|
||||
|
||||
|
||||
POST-INSTALL
|
||||
============
|
||||
Running in the VM:
|
||||
|
||||
Test if your platform is using systemd. First look for the systemd
|
||||
process and then verify that the systemctl tool is available
|
||||
|
||||
ps -ef | grep systemd
|
||||
systemctl --version
|
||||
|
||||
In this case use the systemd instructions, otherwise the sysv
|
||||
instructions.
|
||||
|
||||
systemd:
|
||||
As the root user,
|
||||
systemctl daemon-reload
|
||||
systemctl start guest-client.service
|
||||
systemctl enable guest-client.service
|
||||
|
||||
sysv:
|
||||
As the root user,
|
||||
chkconfig --add guest-client
|
||||
/etc/init.d/guest-client start
|
||||
|
||||
Building into the VM Image:
|
||||
|
||||
systemd:
|
||||
No post install steps required.
|
||||
|
||||
sysv:
|
||||
ln -s /etc/init.d/guest-client /etc/rc#.d/K##guest-client
|
||||
ln -s /etc/init.d/guest-client /etc/rc#.d/S##guest-client
|
||||
|
||||
... and build the VM image.
|
||||
Executable
+385
@@ -0,0 +1,385 @@
|
||||
Copyright(c) 2013-2017, Wind River Systems, Inc.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
* Neither the name of Wind River Systems nor the names of its
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
-----------------------------------------------------------------------
|
||||
|
||||
This file contains instructions for using the Titanium Cloud Guest-Client.
|
||||
|
||||
|
||||
Titanium Cloud Setup
|
||||
=====================
|
||||
The following steps are required to setup the Titanium Cloud to heartbeat
|
||||
a VM.
|
||||
|
||||
1. Create and modify a Flavor for your VM.
|
||||
|
||||
A flavor extraspec, 'Guest Heartbeat', is used to indicate
|
||||
that VMs of this flavor support Titanium Cloud Guest Heartbeat.
|
||||
The default value is 'False'.
|
||||
|
||||
If support is indicated, then as soon as the VM's Titanium Cloud
|
||||
Guest-Client daemon registers with the Titanium Cloud Compute
|
||||
Services on the compute node host, heartbeating will be enabled.
|
||||
|
||||
a) Create a new flavor:
|
||||
|
||||
via dashboard ...
|
||||
- Select 'Admin->Flavors' to bring up the list of flavors
|
||||
- Select '+ Create Flavor' in the upper right.
|
||||
- Fill in the fields as desired
|
||||
- Select 'Create Flavor'
|
||||
|
||||
via command line ...
|
||||
- nova flavor-create ...
|
||||
|
||||
b) Modify the newly created flavor or an existing flavor:
|
||||
|
||||
via dashboard ...
|
||||
- Select 'Admin->Flavors' to bring up the list of flavors
|
||||
- Choose a flavor to modify.
|
||||
- Select the <flavor-name> to go to the Flavor Detail page
|
||||
- Select the Extra Specs TAB
|
||||
- Select '+ Create'
|
||||
- Select 'Guest Heartbeat' from pull-down Extra Spec menu
|
||||
- Check the 'Guest Heartbeat' checkbox
|
||||
- Select 'Create'
|
||||
|
||||
via command line ...
|
||||
- nova flavor-key <flavor-name> set sw:wrs:guest:heartbeat=True
|
||||
|
||||
Note: already running instances that were launched with this
|
||||
flavor are NOT affected.
|
||||
|
||||
2) Launch a new instance of your VM.
|
||||
|
||||
3) Verify your VM is running with Guest Heartbeat enabled.
|
||||
|
||||
Log into the VM.
|
||||
|
||||
Guest-Client logs are written to syslog's 'daemon' facility, which
|
||||
are typically logged by the syslog service to /var/log/daemon.log.
|
||||
Please refer to syslog for details on log settings in order to
|
||||
determine location of logged Guest-Client messages.
|
||||
|
||||
Guest-Client logs are easy to identify. The logs always contain the
|
||||
string 'Guest-Client'. A recursive grep of /var/log is one way to
|
||||
determine where your syslog is sending the Guest-Client logs.
|
||||
|
||||
LOG=`grep -r -l 'Guest-Client' /var/log`
|
||||
echo $LOG
|
||||
|
||||
/var/log/daemon.log
|
||||
|
||||
A successful connection can be verified by looking for the
|
||||
following log.
|
||||
|
||||
grep "Guest-Client" $USER_LOG | grep "heartbeat state change"
|
||||
|
||||
Guest-Client heartbeat state change from enabling to enabled
|
||||
|
||||
|
||||
VM Setup
|
||||
========
|
||||
Configuring Guest-Client Initialization/Start Scripts
|
||||
-----------------------------------------------------
|
||||
The Titanium Cloud communicates with the Guest-Client through a character
|
||||
device. The packaged initialization/startup scripts need to be updated to
|
||||
specify the character device exposed by QEMU to the VM.
|
||||
|
||||
+-- Virtual Machine ---+
|
||||
| |
|
||||
| |
|
||||
Titanium Cloud <-------------------> QEMU <------------> Guest-Client |
|
||||
unix-stream-socket char-device |
|
||||
| |
|
||||
+----------------------+
|
||||
|
||||
The variable that needs updating in the initialization/start scripts is
|
||||
called GUEST_CLIENT_DEVICE.
|
||||
|
||||
Also the location of the Guest-Client binary needs to be updated in the
|
||||
initialization/start scripts. The variable that needs updating is called
|
||||
GUEST_CLIENT.
|
||||
|
||||
|
||||
Configuring Guest Heartbeat & Application Health Check
|
||||
------------------------------------------------------
|
||||
The Guest-Client within your VM will register with the Titanium Cloud
|
||||
Compute Services on the compute node host. Part of that registration
|
||||
process is the specification of a heartbeat interval and a corrective
|
||||
action for a failed/unhealthy VM. The values of heartbeat interval and
|
||||
corrective action come from the guest_heartbeat.conf file and is located
|
||||
in /etc/guest-client/heartbeat directory by default.
|
||||
|
||||
Guest heartbeat works on a challenge response model. The Titanium
|
||||
Server Compute Services on the compute node host will challenge the
|
||||
Guest-Client daemon with a message each interval. The Guest-Client
|
||||
must respond prior to the next interval with a message indicating good
|
||||
health. If the Titanium Cloud Compute Services does not receive a valid
|
||||
response, or if the response specifies that the VM is in ill health, then
|
||||
corrective action is taken.
|
||||
|
||||
The mechanism can be extended by allowing additional VM resident application
|
||||
specific scripts and processes, to register for heartbeating. Each script
|
||||
or process can specify its own heartbeat interval, and its own corrective
|
||||
action to be taken against the VM as a whole. On ill health the Guest-Client
|
||||
reports ill health to the Titanium Cloud Compute Services on the compute node
|
||||
host on the next challenge, and provoke the corrective action.
|
||||
|
||||
This mechanism allows for detection of a failed or hung QEMU/KVM instance,
|
||||
or a failure of the OS within the VM to schedule the Guest-Client process
|
||||
or to route basic IO, or an application level error/failure.
|
||||
|
||||
Configuring the Guest-Client Heartbeat & Application Health Check ...
|
||||
|
||||
The heartbeat interval defaults to every second and can be overridden
|
||||
by the VM in the guest_heartbeat.conf.
|
||||
|
||||
/etc/guest-client/heartbeat/guest_heartbeat.conf:
|
||||
## This specifies the interval between heartbeats in milliseconds between the
|
||||
## guest-client heartbeat and the Titanium Cloud Compute Services on the
|
||||
## compute node host.
|
||||
HB_INTERVAL=1000
|
||||
|
||||
The corrective action defaults to 'reboot' and can be overridden by the
|
||||
VM in the guest_heartbeat.conf.
|
||||
|
||||
/etc/guest-client/heartbeat/guest_heartbeat.conf:
|
||||
## This specifies the corrective action against the VM in the case of a
|
||||
## heartbeat failure between the guest-client and Titanium Cloud Compute
|
||||
## Services on the compute node host and also when the health script
|
||||
## configured below fails.
|
||||
##
|
||||
## Your options are:
|
||||
## "log" Only a log is issued.
|
||||
## "reboot" Issue a reboot against this VM.
|
||||
## "stop" Issue a stop against this VM.
|
||||
##
|
||||
CORRECTIVE_ACTION="reboot"
|
||||
|
||||
A health check script can be registered to run periodically to verify
|
||||
the health of the VM. This is specified in the guest_heartbeat.conf.
|
||||
|
||||
/etc/guest-client/heartbeat/guest_heartbeat.conf:
|
||||
## The Path to the health check script. This is optional.
|
||||
## The script will be called periodically to check for the health of the VM.
|
||||
## The health check interval is specified in seconds.
|
||||
HEALTH_CHECK_INTERVAL=30
|
||||
HEALTH_CHECK_SCRIPT="/etc/guest-client/heartbeat/sample_health_check_script"
|
||||
|
||||
|
||||
Configuring Guest Notifications and Voting
|
||||
------------------------------------------
|
||||
The Guest-Client running in the VM can be used as a conduit for
|
||||
notifications of VM lifecycle events being taken by the Titanium Cloud that
|
||||
will impact this VM. Reboots, pause/resume and migrations are examples of
|
||||
the types of events your VM can be notified of. Depending on the event, a
|
||||
vote on the event maybe required before a notification is sent. Notifications
|
||||
may precede the event, follow it or both. The full table of events and
|
||||
notifications is found below.
|
||||
|
||||
Titanium Action Event Name Vote* Pre-notification Post-notification Timeout
|
||||
--------------- ----------------- ---- ---------------- ----------------- -------
|
||||
stop stop yes yes no shutdown
|
||||
reboot reboot yes yes no shutdown
|
||||
pause pause yes yes no suspend
|
||||
unpause unpause no no yes resume
|
||||
suspend suspend yes yes no suspend
|
||||
resume resume no no yes resume
|
||||
resize resize_begin yes yes no suspend
|
||||
resize_end no no yes resume
|
||||
live-migrate live_migrate_begin yes yes no suspend
|
||||
live_migrate_end no no yes resume
|
||||
cold-migrate cold_migrate_begin yes yes no suspend
|
||||
cold_migrate_end no no yes resume**
|
||||
|
||||
* voting has its own timeout called 'vote' that is event independent.
|
||||
** after VM reboot and reconnection which is subject to the 'restart' timeout.
|
||||
|
||||
Notifications are an opportunity for the VM to take preparatory actions
|
||||
in anticipation of the forthcoming event, or recovery actions after
|
||||
the event has completed. A few examples
|
||||
- A reboot or stop notification might allow the application to stop
|
||||
accepting transactions and cleanly wrap up existing transactions.
|
||||
- A 'resume' notification after a suspend might trigger a time
|
||||
adjustment.
|
||||
- Pre and post migrate notifications might trigger the application
|
||||
to de-register and then re-register with a network load balancer.
|
||||
|
||||
If you register a notification handler, it will receive all events. If
|
||||
an event is not of interest, it should return immediately with a
|
||||
successful return code.
|
||||
|
||||
A process may only register a single notification handler. However
|
||||
multiple processes may independently register handlers. Also a script
|
||||
based handler may be registered via the guest_heartbeat.conf. When
|
||||
multiple processes and scripts register notification handlers, they
|
||||
will be run in parallel.
|
||||
|
||||
Notifications are subject to configurable timeouts. Timeouts are
|
||||
specified by each registered process and in the guest_heartbeat.conf.
|
||||
The timeouts in the guest_heartbeat.conf govern the maximum time all
|
||||
registered notification handlers have to complete.
|
||||
|
||||
While pre-notification handlers are running, the event will be delayed.
|
||||
If the timeout is reached, the event will be allowed to proceed.
|
||||
|
||||
While post-notification handlers are running, or waiting to be run,
|
||||
the Titanium Cloud will not be able to declare the action complete.
|
||||
Keep in mind that many events that offer a post notification will
|
||||
require the VM's Guest-Client to reconnect to the compute host, and
|
||||
that may be further delayed while the VM is rebooted as in a cold
|
||||
migration. When post-notification is finally triggered, it is subject
|
||||
to a timeout as well. If the timeout is reached, the event will be
|
||||
declared complete.
|
||||
|
||||
NOTE: A post-event notification that follows a reboot, as in the
|
||||
cold_migrate_end event, is a special case. It will be triggered as
|
||||
soon as the local heartbeat server reconnects with the compute host,
|
||||
and likely before any processes have a chance to register a handler.
|
||||
The only handler guaranteed to see such a notification is a script
|
||||
directly registered by the Guest-Client itself via guest_heartbeat.conf.
|
||||
|
||||
|
||||
In addition to notifications, there is also an opportunity for the VM
|
||||
to vote on any proposed event. Voting precedes all notifications,
|
||||
and offers the VM a chance to reject the event the Titanium Cloud wishes
|
||||
to initiate. If multiple handlers are registered, it only takes one
|
||||
rejection to abort the event.
|
||||
|
||||
The same handler that handles notifications also handles voting.
|
||||
|
||||
Voting is subject to a configurable timeout. The same timeout applies
|
||||
regardless of the event. The timeout is specified when the Guest-Client
|
||||
registers with compute services on the host. The timeout is specified in
|
||||
the guest_heartbeat.conf file. This timeout governs the maximum time all
|
||||
registered voting handlers have to complete the vote.
|
||||
|
||||
Any voters that fail to vote within the timeout are assumed to have agreed
|
||||
with the proposed action.
|
||||
|
||||
Rejecting an event should be the exception, not the rule, reserved for
|
||||
cases when the VM is handling an exceptionally sensitive operation,
|
||||
as well as a slow operation that can't complete in the notification timeout.
|
||||
An example
|
||||
- an active-standby application deployment (1:1), where the active
|
||||
rejects a shutdown or pause or ... due to its peer standby is not
|
||||
ready or synchronized.
|
||||
|
||||
A vote handler should generally not take any action beyond returning its
|
||||
vote. Just because you vote to accept, doesn't mean all your peers
|
||||
will also accept (i.e. the event might not happen). Taking an action
|
||||
against an event that never happens is almost certainly NOT what you want.
|
||||
Instead save your actions for the notification that follows if no one
|
||||
rejects. The one exception might be to temporarily block the initiation of
|
||||
any new task that would cause you to vote to reject an event in the near
|
||||
future. The theory being that the requester of the event may retry in
|
||||
the near future.
|
||||
|
||||
The Titanium Cloud is not required to offer a vote. Voting may be
|
||||
bypassed on certain recovery scenarios.
|
||||
|
||||
Configuring Guest-Client Notification and Voting ...
|
||||
|
||||
## The overall time to vote in seconds regardless of the event being voted
|
||||
## upon. It should reflect the slowest of all expected voters when in a sane
|
||||
## and healthy condition, plus some allowance for scheduling and messaging.
|
||||
VOTE=8
|
||||
|
||||
## The overall time to handle a stop or reboot notification in seconds.
|
||||
## It should reflect the slowest of all expected notification handlers
|
||||
## when in a sane and healthy condition, plus some allowance for scheduling
|
||||
## and messaging.
|
||||
SHUTDOWN_NOTICE=8
|
||||
|
||||
## The overall time to handle a pause, suspend or migrate-begin notification
|
||||
## in seconds. It should reflect the slowest of all expected notification
|
||||
## handlers when in a sane and healthy condition, plus some allowance for
|
||||
## scheduling and messaging.
|
||||
SUSPEND_NOTICE=8
|
||||
|
||||
## The overall time to handle an unpause, resume or migrate-end notification
|
||||
## in seconds. It should reflect the slowest of all expected notification
|
||||
## handlers when in a sane and healthy condition, plus some allowance for
|
||||
## scheduling and messaging. It does not include reboot time.
|
||||
RESUME_NOTICE=13
|
||||
|
||||
## The overall time to reboot, up to the point the guest-client heartbeat
|
||||
## starts in seconds. Allow for some I/O contention.
|
||||
RESTART=300
|
||||
|
||||
## The Path to the event notification script. This is optional.
|
||||
## The script will be called when an action is initiated that will impact
|
||||
## the VM.
|
||||
##
|
||||
## The event handling script is invoked with two parameters:
|
||||
##
|
||||
## event_handling_script <MSG_TYPE> <EVENT>
|
||||
##
|
||||
## MSG_TYPE is one of:
|
||||
## 'revocable' Indicating a vote is called for. Return zero to accept,
|
||||
## non-zero to reject. For a rejection, the first line of
|
||||
## stdout emitted by the script will be captured and logged
|
||||
## logged indicating why the event was rejected.
|
||||
##
|
||||
## 'irrevocable' Indicating this is a notification only. Take preparatory
|
||||
## actions and return zero if successful, or non-zero on
|
||||
## failure. For a failure, the first line of stdout
|
||||
## emitted by the script will be captured and logged
|
||||
## indicating the cause of the failure.
|
||||
##
|
||||
## EVENT is one of: ( 'stop', 'reboot', 'pause', 'unpause', 'suspend',
|
||||
## 'resume', 'live_migrate_begin',
|
||||
## 'live_migrate_end', 'cold_migrate_begin',
|
||||
## 'cold_migrate_end' )
|
||||
##
|
||||
EVENT_NOTIFICATION_SCRIPT="/etc/guest-client/heartbeat/sample_event_handling_script"
|
||||
|
||||
|
||||
VM Application Setup
|
||||
====================
|
||||
An application running in the VM may wish to register directly for voting
|
||||
and notifications. See the guest_heartbeat_api.h for more details. A
|
||||
working example can be found in the guest_client_api source directory in the
|
||||
sample_guest_app.c file.
|
||||
|
||||
To compile the sample-guest-app run ...
|
||||
cd wrs-guest-heartbeat-3.0.0
|
||||
make sample
|
||||
|
||||
This will create an executable called sample-guest-app in the 'build'
|
||||
directory.
|
||||
|
||||
When compiling the guest application ...
|
||||
|
||||
include headers:
|
||||
#include <guest_api_types.h>
|
||||
#include <guest_ap_debug.h>
|
||||
#include <guest_heartbeat_api.h>
|
||||
|
||||
link with:
|
||||
-lguest_common_api -lguest_heartbeat_api
|
||||
Binary file not shown.
Binary file not shown.
+84
@@ -0,0 +1,84 @@
|
||||
#
|
||||
# Copyright(c) 2013-2016, Wind River Systems, Inc.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in
|
||||
# the documentation and/or other materials provided with the
|
||||
# distribution.
|
||||
# * Neither the name of Wind River Systems nor the names of its
|
||||
# contributors may be used to endorse or promote products derived
|
||||
# from this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
SHELL = /bin/sh
|
||||
|
||||
## Configuration Directory Variables
|
||||
prefix := /usr/local
|
||||
exec_prefix := $(prefix)
|
||||
sysconfdir := $(prefix)/etc
|
||||
includedir := $(prefix)/include
|
||||
libdir := $(exec_prefix)/lib
|
||||
bindir := $(exec_prefix)/bin
|
||||
|
||||
MAKEFILE_PATH := $(abspath $(lastword $(MAKEFILE_LIST)))
|
||||
CURRENT_DIR := $(patsubst %/,%,$(dir $(MAKEFILE_PATH)))
|
||||
BUILD_DIR := $(CURRENT_DIR)/build
|
||||
CONFIG_DIR := $(sysconfdir)/guest-client/heartbeat
|
||||
PACKAGE_DIR := $(BUILD_DIR)/package
|
||||
PACKAGE_ROOT_DIR := $(PACKAGE_DIR)/rootdir
|
||||
|
||||
.PHONY: all build sample clean distclean package
|
||||
|
||||
all: build
|
||||
|
||||
build:
|
||||
mkdir -p --mode 755 $(BUILD_DIR)
|
||||
@(cd src; make --no-print-directory build \
|
||||
sysconfdir=$(sysconfdir) BUILD_DIR=$(BUILD_DIR))
|
||||
|
||||
sample:
|
||||
@:
|
||||
|
||||
clean:
|
||||
@-(cd src; make --no-print-directory clean BUILD_DIR=$(BUILD_DIR))
|
||||
|
||||
distclean: clean
|
||||
|
||||
package:
|
||||
@(mkdir -p --mode 755 $(PACKAGE_DIR))
|
||||
@(echo "Packaging guest-client.init in $(PACKAGE_DIR)")
|
||||
@(cp $(CURRENT_DIR)/scripts/guest-client.init $(PACKAGE_DIR)/guest-client.init)
|
||||
@(chmod 755 $(PACKAGE_DIR)/guest-client.init)
|
||||
@(echo "Packaging guest-client.service in $(PACKAGE_DIR)")
|
||||
@(cp $(CURRENT_DIR)/scripts/guest-client.service $(PACKAGE_DIR)/guest-client.service)
|
||||
@(chmod 644 $(PACKAGE_DIR)/guest-client.service)
|
||||
@(echo "Packaging guest-client.systemd in $(PACKAGE_DIR)")
|
||||
@(cp $(CURRENT_DIR)/scripts/guest-client.systemd $(PACKAGE_DIR)/guest-client.systemd)
|
||||
@(mkdir -p --mode 755 $(PACKAGE_ROOT_DIR)/$(CONFIG_DIR))
|
||||
@(echo "Packaging guest_heartbeat.conf in $(PACKAGE_ROOT_DIR)/$(CONFIG_DIR)")
|
||||
@(cp $(CURRENT_DIR)/scripts/guest_heartbeat.conf $(PACKAGE_ROOT_DIR)/$(CONFIG_DIR)/guest_heartbeat.conf)
|
||||
@(echo "Packaging sample_event_handling_script in $(PACKAGE_ROOT_DIR)/$(CONFIG_DIR)")
|
||||
@(cp $(CURRENT_DIR)/scripts/sample_event_handling_script $(PACKAGE_ROOT_DIR)/$(CONFIG_DIR)/sample_event_handling_script)
|
||||
@(echo "Packaging sample_health_check_script in $(PACKAGE_ROOT_DIR)/$(CONFIG_DIR)")
|
||||
@(cp $(CURRENT_DIR)/scripts/sample_health_check_script $(PACKAGE_ROOT_DIR)/$(CONFIG_DIR)/sample_health_check_script)
|
||||
@-(cd src; make --no-print-directory package BUILD_DIR=$(BUILD_DIR) \
|
||||
PACKAGE_DIR=$(PACKAGE_DIR) prefix=$(prefix) exec_prefix=$(exec_prefix) \
|
||||
sysconfdir=$(sysconfdir) includedir=$(includedir) libdir=$(libdir) \
|
||||
bindir=$(bindir))
|
||||
@@ -0,0 +1,183 @@
|
||||
#! /bin/sh
|
||||
#
|
||||
# Copyright(c) 2013-2016, Wind River Systems, Inc.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in
|
||||
# the documentation and/or other materials provided with the
|
||||
# distribution.
|
||||
# * Neither the name of Wind River Systems nor the names of its
|
||||
# contributors may be used to endorse or promote products derived
|
||||
# from this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
|
||||
#
|
||||
# chkconfig: - 96 96
|
||||
#
|
||||
### BEGIN INIT INFO
|
||||
# Short-Description: Guest-Client
|
||||
# Provides: guest-client
|
||||
# Default-Start: 3 5
|
||||
# Default-Stop: 0 1 2 6
|
||||
# Required-Start:
|
||||
# Required-Stop:
|
||||
### END INIT INFO
|
||||
|
||||
# Assumes that LSB (Linux Standard Base) scripts are available. On Fedora and
|
||||
# other Red Hat related distros, the redhat-lsb package is optional.
|
||||
if [ -f /etc/init.d/functions ]
|
||||
then
|
||||
. /etc/init.d/functions
|
||||
else
|
||||
. /lib/lsb/init-functions
|
||||
fi
|
||||
|
||||
# LSB Exit Codes
|
||||
# 0 - success
|
||||
# 1 - generic or unspecified error
|
||||
# 2 - invalid or excess arguments
|
||||
# 3 - unimplemented feature
|
||||
# 4 - user had insufficient privileges
|
||||
# 5 - program is not installed
|
||||
# 6 - program is not configured
|
||||
# 7 - program is not running
|
||||
#
|
||||
# LSB Exit Status Codes
|
||||
# 0 - program is running or service OK
|
||||
# 1 - program is dead and /var/run pid file exists
|
||||
# 2 - program is dead and /var/lock lock file exists
|
||||
# 3 - program is not running
|
||||
# 4 - program or service status is unknown
|
||||
#
|
||||
RETVAL=0
|
||||
|
||||
# Update binary location and device to be used, if necessary.
|
||||
GUEST_CLIENT_NAME="guest-client"
|
||||
GUEST_CLIENT_PIDFILE="/var/run/${GUEST_CLIENT_NAME}.pid"
|
||||
GUEST_CLIENT="/usr/bin/${GUEST_CLIENT_NAME}"
|
||||
GUEST_CLIENT_DEVICE="/dev/virtio-ports/cgcs.heartbeat"
|
||||
|
||||
if [ ! -e "${GUEST_CLIENT}" ]
|
||||
then
|
||||
echo "${GUEST_CLIENT} is missing"
|
||||
exit 5
|
||||
fi
|
||||
|
||||
PATH=/sbin:/usr/sbin:/bin:/usr/bin:/usr/local/bin
|
||||
|
||||
case "$1" in
|
||||
start)
|
||||
args=""
|
||||
if [ -n ${GUEST_CLIENT_DEVICE} ]
|
||||
then
|
||||
args="--device ${GUEST_CLIENT_DEVICE}"
|
||||
fi
|
||||
|
||||
echo -n "Starting ${GUEST_CLIENT_NAME}: "
|
||||
if [ -n "`pidof ${GUEST_CLIENT}`" ]
|
||||
then
|
||||
# Something might have started guest-client already.
|
||||
RETVAL=0
|
||||
else
|
||||
start-stop-daemon --start --background --make-pidfile --pidfile ${GUEST_CLIENT_PIDFILE} --exec ${GUEST_CLIENT} -- ${args}
|
||||
RETVAL=$?
|
||||
fi
|
||||
if [ ${RETVAL} -eq 0 ]
|
||||
then
|
||||
echo "OK"
|
||||
else
|
||||
echo "FAIL"
|
||||
RETVAL=1
|
||||
fi
|
||||
;;
|
||||
|
||||
stop)
|
||||
echo -n "Stopping ${GUEST_CLIENT_NAME}: "
|
||||
if [ -n "`pidof ${GUEST_CLIENT}`" ]
|
||||
then
|
||||
killproc ${GUEST_CLIENT}
|
||||
fi
|
||||
|
||||
SHUTDOWN_TIMEOUT=10
|
||||
count=0
|
||||
while [ ${count} -lt ${SHUTDOWN_TIMEOUT} ]
|
||||
do
|
||||
pidof ${GUEST_CLIENT} &> /dev/null
|
||||
rc=$?
|
||||
if [ ${rc} -eq 1 ]
|
||||
then
|
||||
echo "OK"
|
||||
break
|
||||
fi
|
||||
count=`expr ${count} + 1`
|
||||
sleep 1
|
||||
done
|
||||
|
||||
pidof ${GUEST_CLIENT} &> /dev/null
|
||||
rc=$?
|
||||
if [ ${rc} -eq 0 ]
|
||||
then
|
||||
echo "FAIL"
|
||||
RETVAL=1
|
||||
fi
|
||||
|
||||
rm -f ${GUEST_CLIENT_PIDFILE}
|
||||
;;
|
||||
|
||||
status)
|
||||
pid=`cat ${GUEST_CLIENT_PIDFILE} 2>/dev/null`
|
||||
if [ -n "${pid}" ]
|
||||
then
|
||||
if ps -p ${pid} &>/dev/null
|
||||
then
|
||||
echo "${GUEST_CLIENT_NAME} is running"
|
||||
RETVAL=0
|
||||
else
|
||||
echo "${GUEST_CLIENT_NAME} is not running but has pid file"
|
||||
RETVAL=1
|
||||
fi
|
||||
else
|
||||
echo "${GUEST_CLIENT_NAME} is not running"
|
||||
RETVAL=3
|
||||
fi
|
||||
;;
|
||||
|
||||
restart)
|
||||
$0 stop
|
||||
sleep 1
|
||||
$0 start
|
||||
;;
|
||||
|
||||
reload)
|
||||
pid=`cat ${GUEST_CLIENT_PIDFILE} 2>/dev/null`
|
||||
if [ -n "${pid}" ]
|
||||
then
|
||||
echo "${GUEST_CLIENT_NAME} reload"
|
||||
kill -HUP ${pid}
|
||||
fi
|
||||
;;
|
||||
|
||||
*)
|
||||
echo "usage: $0 { start | stop | status | restart | reload }"
|
||||
;;
|
||||
esac
|
||||
|
||||
exit ${RETVAL}
|
||||
@@ -0,0 +1,57 @@
|
||||
#
|
||||
# Copyright(c) 2013-2016, Wind River Systems, Inc.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in
|
||||
# the documentation and/or other materials provided with the
|
||||
# distribution.
|
||||
# * Neither the name of Wind River Systems nor the names of its
|
||||
# contributors may be used to endorse or promote products derived
|
||||
# from this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
|
||||
[Unit]
|
||||
Description=Titanium Guest-Client
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=forking
|
||||
PIDFile=/var/run/guest-client.pid
|
||||
EnvironmentFile=/etc/guest-client/heartbeat/guest_heartbeat.conf
|
||||
ExecStart=/etc/guest-client/guest-client.systemd start
|
||||
ExecStop=/etc/guest-client/guest-client.systemd stop
|
||||
ExecReload=/etc/guest-client/guest-client.systemd restart
|
||||
# We want systemd to give guest-client some time to finish gracefully, but
|
||||
# still want it to kill guest-client after TimeoutStopSec if something went
|
||||
# wrong during the graceful stop. Normally, systemd sends SIGTERM signal right
|
||||
# after the ExecStop, which would kill heartbeat. We are sending useless SIGCONT
|
||||
# here to give guest-client time to finish.
|
||||
KillSignal=SIGCONT
|
||||
# Exit code of 6 indicates it is not configured and no restart.
|
||||
# if /dev/virtio-ports/cgcs.heartbeat is not found, guest-client
|
||||
# returns 6 on exit. We don't want to keep restarting guest-client
|
||||
# if it is not configured.
|
||||
RestartPreventExitStatus=6
|
||||
Restart=always
|
||||
RestartSec=15
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
@@ -0,0 +1,171 @@
|
||||
#! /bin/sh
|
||||
#
|
||||
# Copyright(c) 2013-2016, Wind River Systems, Inc.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in
|
||||
# the documentation and/or other materials provided with the
|
||||
# distribution.
|
||||
# * Neither the name of Wind River Systems nor the names of its
|
||||
# contributors may be used to endorse or promote products derived
|
||||
# from this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
|
||||
# Assumes that LSB (Linux Standard Base) scripts are available. On Fedora and
|
||||
# other Red Hat related distros, the redhat-lsb package is optional.
|
||||
if [ -f /etc/init.d/functions ]
|
||||
then
|
||||
. /etc/init.d/functions
|
||||
else
|
||||
. /lib/lsb/init-functions
|
||||
fi
|
||||
|
||||
# LSB Exit Codes
|
||||
# 0 - success
|
||||
# 1 - generic or unspecified error
|
||||
# 2 - invalid or excess arguments
|
||||
# 3 - unimplemented feature
|
||||
# 4 - user had insufficient privileges
|
||||
# 5 - program is not installed
|
||||
# 6 - program is not configured
|
||||
# 7 - program is not running
|
||||
#
|
||||
# LSB Exit Status Codes
|
||||
# 0 - program is running or service OK
|
||||
# 1 - program is dead and /var/run pid file exists
|
||||
# 2 - program is dead and /var/lock lock file exists
|
||||
# 3 - program is not running
|
||||
# 4 - program or service status is unknown
|
||||
#
|
||||
RETVAL=0
|
||||
|
||||
# Update binary location and device to be used, if necessary.
|
||||
GUEST_CLIENT_NAME="guest-client"
|
||||
GUEST_CLIENT_PIDFILE="/var/run/${GUEST_CLIENT_NAME}.pid"
|
||||
GUEST_CLIENT="/usr/local/bin/${GUEST_CLIENT_NAME}"
|
||||
GUEST_CLIENT_DEVICE="/dev/virtio-ports/cgcs.heartbeat"
|
||||
|
||||
if [ ! -e "${GUEST_CLIENT}" ]
|
||||
then
|
||||
echo "${GUEST_CLIENT} is missing"
|
||||
exit 5
|
||||
fi
|
||||
|
||||
PATH=/sbin:/usr/sbin:/bin:/usr/bin:/usr/local/bin
|
||||
|
||||
case "$1" in
|
||||
start)
|
||||
args=""
|
||||
if [ -n ${GUEST_CLIENT_DEVICE} ]
|
||||
then
|
||||
args="--device ${GUEST_CLIENT_DEVICE}"
|
||||
fi
|
||||
|
||||
echo -n "Starting ${GUEST_CLIENT_NAME}: "
|
||||
if [ -n "`pidof ${GUEST_CLIENT}`" ]
|
||||
then
|
||||
# Something might have started guest-client already.
|
||||
RETVAL=0
|
||||
else
|
||||
start-stop-daemon --start --background --make-pidfile --pidfile ${GUEST_CLIENT_PIDFILE} --exec ${GUEST_CLIENT} -- ${args}
|
||||
RETVAL=$?
|
||||
fi
|
||||
if [ ${RETVAL} -eq 0 ]
|
||||
then
|
||||
echo "OK"
|
||||
else
|
||||
echo "FAIL"
|
||||
RETVAL=1
|
||||
fi
|
||||
;;
|
||||
|
||||
stop)
|
||||
echo -n "Stopping ${GUEST_CLIENT_NAME}: "
|
||||
if [ -n "`pidof ${GUEST_CLIENT}`" ]
|
||||
then
|
||||
killproc ${GUEST_CLIENT}
|
||||
fi
|
||||
|
||||
SHUTDOWN_TIMEOUT=10
|
||||
count=0
|
||||
while [ ${count} -lt ${SHUTDOWN_TIMEOUT} ]
|
||||
do
|
||||
pidof ${GUEST_CLIENT} &> /dev/null
|
||||
rc=$?
|
||||
if [ ${rc} -eq 1 ]
|
||||
then
|
||||
echo "OK"
|
||||
break
|
||||
fi
|
||||
count=`expr ${count} + 1`
|
||||
sleep 1
|
||||
done
|
||||
|
||||
pidof ${GUEST_CLIENT} &> /dev/null
|
||||
rc=$?
|
||||
if [ ${rc} -eq 0 ]
|
||||
then
|
||||
echo "FAIL"
|
||||
RETVAL=1
|
||||
fi
|
||||
|
||||
rm -f ${GUEST_CLIENT_PIDFILE}
|
||||
;;
|
||||
|
||||
status)
|
||||
pid=`cat ${GUEST_CLIENT_PIDFILE} 2>/dev/null`
|
||||
if [ -n "${pid}" ]
|
||||
then
|
||||
if ps -p ${pid} &>/dev/null
|
||||
then
|
||||
echo "${GUEST_CLIENT_NAME} is running"
|
||||
RETVAL=0
|
||||
else
|
||||
echo "${GUEST_CLIENT_NAME} is not running but has pid file"
|
||||
RETVAL=1
|
||||
fi
|
||||
else
|
||||
echo "${GUEST_CLIENT_NAME} is not running"
|
||||
RETVAL=3
|
||||
fi
|
||||
;;
|
||||
|
||||
restart)
|
||||
$0 stop
|
||||
sleep 1
|
||||
$0 start
|
||||
;;
|
||||
|
||||
reload)
|
||||
pid=`cat ${GUEST_CLIENT_PIDFILE} 2>/dev/null`
|
||||
if [ -n "${pid}" ]
|
||||
then
|
||||
echo "${GUEST_CLIENT_NAME} reload"
|
||||
kill -HUP ${pid}
|
||||
fi
|
||||
;;
|
||||
|
||||
*)
|
||||
echo "usage: $0 { start | stop | status | restart | reload }"
|
||||
;;
|
||||
esac
|
||||
|
||||
exit ${RETVAL}
|
||||
@@ -0,0 +1,116 @@
|
||||
###
|
||||
# Copyright (c) <2013-2017>, Wind River Systems, Inc.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without modification,
|
||||
# are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 1) Redistributions of source code must retain the above copyright notice,
|
||||
# this list of conditions and the following disclaimer.
|
||||
#
|
||||
# 2) Redistributions in binary form must reproduce the above copyright notice,
|
||||
# this list of conditions and the following disclaimer in the documentation and/or
|
||||
# other materials provided with the distribution.
|
||||
#
|
||||
# 3) Neither the name of Wind River Systems nor the names of its contributors may be
|
||||
# used to endorse or promote products derived from this software without specific
|
||||
# prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
###
|
||||
|
||||
##################################################
|
||||
## Heartbeat health check options
|
||||
|
||||
## This specifies the interval between heartbeats in milliseconds between the
|
||||
## guest-client heartbeat and the Titanium Cloud Compute Services on the
|
||||
## compute node host.
|
||||
HB_INTERVAL=1000
|
||||
|
||||
## This specifies the corrective action against the VM in the case of a
|
||||
## heartbeat failure between the guest-client and Titanium Cloud Compute
|
||||
## Services on the compute node host and also when the health script
|
||||
## configured below fails.
|
||||
##
|
||||
## Your options are:
|
||||
## "log" Only a log is issued.
|
||||
## "reboot" Issue a reboot against this VM.
|
||||
## "stop" Issue a stop against this VM.
|
||||
##
|
||||
CORRECTIVE_ACTION="reboot"
|
||||
|
||||
|
||||
##################################################
|
||||
## Heartbeat event notification and voting options
|
||||
|
||||
## The overall time to vote in seconds regardless of the event being voted
|
||||
## upon. It should reflect the slowest of all expected voters when in a sane
|
||||
## and healthy condition, plus some allowance for scheduling and messaging.
|
||||
VOTE=8
|
||||
|
||||
## The overall time to handle a stop or reboot notification in seconds.
|
||||
## It should reflect the slowest of all expected notification handlers
|
||||
## when in a sane and healthy condition, plus some allowance for scheduling
|
||||
## and messaging.
|
||||
SHUTDOWN_NOTICE=8
|
||||
|
||||
## The overall time to handle a pause, suspend or migrate-begin notification
|
||||
## in seconds. It should reflect the slowest of all expected notification
|
||||
## handlers when in a sane and healthy condition, plus some allowance for
|
||||
## scheduling and messaging.
|
||||
SUSPEND_NOTICE=8
|
||||
|
||||
## The overall time to handle an unpause, resume or migrate-end notification
|
||||
## in seconds. It should reflect the slowest of all expected notification
|
||||
## handlers when in a sane and healthy condition, plus some allowance for
|
||||
## scheduling and messaging. It does not include reboot time.
|
||||
RESUME_NOTICE=13
|
||||
|
||||
## The overall time to reboot, up to the point the guest-client heartbeat
|
||||
## starts in seconds. Allow for some I/O contention.
|
||||
RESTART=600
|
||||
|
||||
|
||||
##################################################
|
||||
## The Path to the health check script. This is optional.
|
||||
## The script will be called periodically to check for the health of the VM.
|
||||
## The health check interval is specified in seconds.
|
||||
HEALTH_CHECK_INTERVAL=30
|
||||
HEALTH_CHECK_SCRIPT="/etc/guest-client/heartbeat/sample_health_check_script"
|
||||
|
||||
|
||||
##################################################
|
||||
## The Path to the event notification script. This is optional.
|
||||
## The script will be called when an action is initiated that will impact
|
||||
## the VM.
|
||||
##
|
||||
## The event handling script is invoked with two parameters:
|
||||
##
|
||||
## event_handling_script <MSG_TYPE> <EVENT>
|
||||
##
|
||||
## MSG_TYPE is one of:
|
||||
## 'revocable' Indicating a vote is called for. Return zero to accept,
|
||||
## non-zero to reject. For a rejection, the first line of
|
||||
## stdout emitted by the script will be captured and logged
|
||||
## logged indicating why the event was rejected.
|
||||
##
|
||||
## 'irrevocable' Indicating this is a notification only. Take preparatory
|
||||
## actions and return zero if successful, or non-zero on
|
||||
## failure. For a failure, the first line of stdout
|
||||
## emitted by the script will be captured and logged
|
||||
## indicating the cause of the failure.
|
||||
##
|
||||
## EVENT is one of: ( 'stop', 'reboot', 'pause', 'unpause', 'suspend',
|
||||
## 'resume', 'live_migrate_begin',
|
||||
## 'live_migrate_end', 'cold_migrate_begin',
|
||||
## 'cold_migrate_end' )
|
||||
##
|
||||
EVENT_NOTIFICATION_SCRIPT="/etc/guest-client/heartbeat/sample_event_handling_script"
|
||||
+165
@@ -0,0 +1,165 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright(c) 2013-2016, Wind River Systems, Inc.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in
|
||||
# the documentation and/or other materials provided with the
|
||||
# distribution.
|
||||
# * Neither the name of Wind River Systems nor the names of its
|
||||
# contributors may be used to endorse or promote products derived
|
||||
# from this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
|
||||
MSG_TYPE=$1
|
||||
EVENT=$2
|
||||
|
||||
FILE="/tmp/event_timeout"
|
||||
if [ -f $FILE ];
|
||||
then
|
||||
echo "File $FILE exists."
|
||||
logger "File $FILE exists. Run slowly to trigger timeout"
|
||||
sleep 300
|
||||
logger "$FILE induced delay ends"
|
||||
else
|
||||
logger "File $FILE does not exist."
|
||||
fi
|
||||
|
||||
if [ "$MSG_TYPE" == "revocable" ]
|
||||
then
|
||||
# Vote on the proposed action ( 0 == agree, 1 == reject )
|
||||
# Take no actions yet.
|
||||
# If no other parties have rejected the proposed action, an "irrevocable"
|
||||
# notification will soon follow.
|
||||
|
||||
if [ $EVENT == "stop" ]
|
||||
then
|
||||
FILE="/tmp/vote_no_to_stop"
|
||||
|
||||
elif [ "$EVENT" == "reboot" ]
|
||||
then
|
||||
FILE="/tmp/vote_no_to_reboot"
|
||||
|
||||
elif [ "$EVENT" == "suspend" ] || [ "$EVENT" == "pause" ]
|
||||
then
|
||||
FILE="/tmp/vote_no_to_suspend"
|
||||
|
||||
elif [ "$EVENT" == "live_migrate_begin" ] || [ "$EVENT" == "cold_migrate_begin" ]
|
||||
then
|
||||
FILE="/tmp/vote_no_to_migrate"
|
||||
|
||||
elif [ "$EVENT" == "resize_begin" ]
|
||||
then
|
||||
FILE="/tmp/vote_no_to_resize"
|
||||
|
||||
elif [ "$EVENT" == "live_migrate_end" ] || [ "$EVENT" == "cold_migrate_end" ] ||
|
||||
[ "$EVENT" == "resize_end" ] || [ "$EVENT" == "unpause" ] ||
|
||||
[ "$EVENT" == "resume" ]
|
||||
then
|
||||
logger "Should never be asked to vote on $EVENT"
|
||||
echo "Should never be asked to vote on $EVENT"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -f $FILE ];
|
||||
then
|
||||
echo "File $FILE exists."
|
||||
logger "File $FILE exists."
|
||||
logger "Vote against $EVENT at this time."
|
||||
|
||||
# Vote no to shutdown.
|
||||
exit 1
|
||||
else
|
||||
echo "File $FILE does not exist."
|
||||
logger "File $FILE does not exists."
|
||||
logger "Vote to allow $EVENT"
|
||||
|
||||
# Vote yes to shutdown.
|
||||
exit 0
|
||||
fi
|
||||
|
||||
elif [ "$MSG_TYPE" == "irrevocable" ]
|
||||
then
|
||||
|
||||
if [ $EVENT == "stop" ]
|
||||
then
|
||||
logger "Notification of pending $EVENT received."
|
||||
# Place clean shutdown actions here. Idea is to hand off activity and
|
||||
# cleanly stop the payload application. It is not required to stop the
|
||||
# kernel, an ACPI power-off event will follow.
|
||||
|
||||
elif [ "$EVENT" == "reboot" ]
|
||||
then
|
||||
logger "Notification of pending $EVENT received."
|
||||
# Place clean shutdown actions here. Idea is to hand off activity and
|
||||
# cleanly stop the application. It is not required to stop/reboot the
|
||||
# kernel, an ACPI power-off event will follow, and then a power-on
|
||||
|
||||
elif [ "$EVENT" == "pause" ] || [ "$EVENT" == "suspend" ]
|
||||
then
|
||||
logger "Notification of pending $EVENT received."
|
||||
# This VM will be paused or suspended but not rebooted.
|
||||
# Hand off activity and cleanly stop the application if required.
|
||||
|
||||
elif [ "$EVENT" == "unpause" ] || [ "$EVENT" == "resume" ]
|
||||
then
|
||||
logger "Notification of $EVENT completion received."
|
||||
# This VM has resumed from a paused or suspended state.
|
||||
# Restart your application and take activity as required.
|
||||
|
||||
elif [ "$EVENT" == "resize_begin" ]
|
||||
then
|
||||
logger "Notification of pending resize received. ($EVENT)"
|
||||
# This VM will soon be resized.
|
||||
# Hand off activity and cleanly stop the payload application if required.
|
||||
|
||||
elif [ "$EVENT" == "resize_end" ]
|
||||
then
|
||||
logger "Notification of resize complete received."
|
||||
# This VM has been resized.
|
||||
# Restart your application and/or re-establish your network connectivity
|
||||
# as required.
|
||||
|
||||
elif [ "$EVENT" == "live_migrate_begin" ] || [ "$EVENT" == "cold_migrate_begin" ]
|
||||
then
|
||||
logger "Notification of pending migration received. ($EVENT)"
|
||||
# This VM will soon relocate to a different host.
|
||||
# Network connectivity may change.
|
||||
# Hand off activity and cleanly stop the payload application if required.
|
||||
|
||||
elif [ "$EVENT" == "live_migrate_end" ] || [ "$EVENT" == "cold_migrate_end" ]
|
||||
then
|
||||
logger "Notification of migration complete received."
|
||||
# This VM has finished relocation to a new host.
|
||||
# Network connectivity may have changed.
|
||||
# Restart your application and/or re-establish your network connectivity
|
||||
# as required.
|
||||
fi
|
||||
|
||||
sleep 1
|
||||
exit 0
|
||||
|
||||
else
|
||||
echo "Unknown message type '$MSG_TYPE'"
|
||||
logger "Unknown message type '$MSG_TYPE'"
|
||||
sleep 1
|
||||
exit -1
|
||||
fi
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright(c) 2013-2016, Wind River Systems, Inc.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in
|
||||
# the documentation and/or other materials provided with the
|
||||
# distribution.
|
||||
# * Neither the name of Wind River Systems nor the names of its
|
||||
# contributors may be used to endorse or promote products derived
|
||||
# from this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
|
||||
FILE="/tmp/unhealthy"
|
||||
if [ -f $FILE ];
|
||||
then
|
||||
echo "File $FILE exists."
|
||||
rm -f $FILE
|
||||
exit 1
|
||||
else
|
||||
echo "File $FILE does not exist."
|
||||
fi
|
||||
|
||||
exit 0
|
||||
@@ -0,0 +1,94 @@
|
||||
#
|
||||
# Copyright(c) 2013-2016, Wind River Systems, Inc.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in
|
||||
# the documentation and/or other materials provided with the
|
||||
# distribution.
|
||||
# * Neither the name of Wind River Systems nor the names of its
|
||||
# contributors may be used to endorse or promote products derived
|
||||
# from this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
SHELL = /bin/sh
|
||||
|
||||
## Configuration Directory Variables
|
||||
prefix := /usr/local
|
||||
exec_prefix := $(prefix)
|
||||
sysconfdir := $(prefix)/etc
|
||||
includedir := $(prefix)/include
|
||||
libdir := $(exec_prefix)/lib
|
||||
bindir := $(exec_prefix)/bin
|
||||
|
||||
MAKEFILE_PATH := $(abspath $(lastword $(MAKEFILE_LIST)))
|
||||
CURRENT_DIR := $(patsubst %/,%,$(dir $(MAKEFILE_PATH)))
|
||||
|
||||
ifndef BUILD_DIR
|
||||
$(error BUILD_DIR undefined)
|
||||
endif
|
||||
|
||||
PACKAGE_DIR := $(BUILD_DIR)/package
|
||||
PACKAGE_ROOT_DIR := $(PACKAGE_DIR)/rootdir
|
||||
|
||||
.SUFFIXES:
|
||||
.SUFFIXES: .c .o
|
||||
|
||||
.PHONY: all build heartbeat clean distclean package
|
||||
|
||||
heartbeat_C_SRCS := $(wildcard $(CURRENT_DIR)/heartbeat/*.c)
|
||||
heartbeat_C_SRCS := $(subst $(CURRENT_DIR)/heartbeat/,,$(heartbeat_C_SRCS))
|
||||
heartbeat_C_OBJS := ${heartbeat_C_SRCS:.c=.o}
|
||||
|
||||
program_NAME := guest-client
|
||||
program_C_INCLUDES := -I$(CURRENT_DIR) -I$(CURRENT_DIR)/heartbeat
|
||||
program_C_INCLUDES += -I$(CURRENT_DIR)/../../include
|
||||
program_C_SRCS := $(wildcard *.c)
|
||||
program_C_OBJS := ${program_C_SRCS:.c=.o}
|
||||
program_LDLIBS := -lrt
|
||||
program_BUILD_OBJS := $(addprefix $(BUILD_DIR)/, $(heartbeat_C_OBJS))
|
||||
program_BUILD_OBJS += $(addprefix $(BUILD_DIR)/, $(program_C_OBJS))
|
||||
|
||||
CFLAGS = -g -O2 -Wall -Werror -Wformat -DSYSCONFDIR=$(sysconfdir)
|
||||
|
||||
all: build
|
||||
|
||||
heartbeat:
|
||||
@(cd heartbeat; make --no-print-directory build \
|
||||
sysconfdir=$(sysconfdir) BUILD_DIR=$(BUILD_DIR))
|
||||
|
||||
%.o: %.c
|
||||
$(CC) $(CFLAGS) $(program_C_INCLUDES) -c $^ -o $(BUILD_DIR)/$@
|
||||
|
||||
$(program_NAME): heartbeat $(program_C_OBJS)
|
||||
$(CC) $(CFLAGS) $(program_BUILD_OBJS) $(program_LDLIBS) \
|
||||
-o $(BUILD_DIR)/$(program_NAME) -ljson-c
|
||||
|
||||
build: $(program_NAME)
|
||||
|
||||
clean:
|
||||
@-($(RM) -Rf $(BUILD_DIR)/*)
|
||||
|
||||
distclean: clean
|
||||
|
||||
package:
|
||||
@(mkdir -p --mode 755 $(PACKAGE_ROOT_DIR)/$(bindir))
|
||||
@(echo "Packaging $(program_NAME) in $(PACKAGE_ROOT_DIR)/$(bindir)")
|
||||
@(cp $(BUILD_DIR)/$(program_NAME) $(PACKAGE_ROOT_DIR)/$(bindir)/$(program_NAME))
|
||||
@(chmod 755 $(PACKAGE_ROOT_DIR)/$(bindir)/$(program_NAME))
|
||||
@@ -0,0 +1,351 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2016, Wind River Systems, Inc.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1) Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2) Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* 3) Neither the name of Wind River Systems nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software without specific
|
||||
* prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "guest_channel.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "guest_limits.h"
|
||||
#include "guest_types.h"
|
||||
#include "guest_debug.h"
|
||||
#include "guest_unix.h"
|
||||
|
||||
typedef struct {
|
||||
bool inuse;
|
||||
bool char_device;
|
||||
int sock;
|
||||
char dev_name[GUEST_DEVICE_NAME_MAX_CHAR];
|
||||
} GuestChannelT;
|
||||
|
||||
static GuestChannelT _channel[GUEST_MAX_CONNECTIONS];
|
||||
|
||||
// ****************************************************************************
|
||||
// Guest Channel - Find Empty
|
||||
// ==========================
|
||||
static GuestChannelIdT guest_channel_find_empty( void )
|
||||
{
|
||||
GuestChannelT* channel = NULL;
|
||||
|
||||
unsigned int channel_id;
|
||||
for (channel_id=0; GUEST_MAX_CONNECTIONS > channel_id; ++channel_id)
|
||||
{
|
||||
channel = &(_channel[channel_id]);
|
||||
if (!channel->inuse)
|
||||
return channel_id;
|
||||
}
|
||||
|
||||
return GUEST_CHANNEL_ID_INVALID;
|
||||
}
|
||||
// ****************************************************************************
|
||||
|
||||
// ****************************************************************************
|
||||
// Guest Channel - Find
|
||||
// ====================
|
||||
static GuestChannelT* guest_channel_find( GuestChannelIdT channel_id )
|
||||
{
|
||||
GuestChannelT* channel = NULL;
|
||||
|
||||
if ((0 <= channel_id)&&(GUEST_MAX_CONNECTIONS > channel_id))
|
||||
{
|
||||
channel = &(_channel[channel_id]);
|
||||
if (channel->inuse)
|
||||
return channel;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
// ****************************************************************************
|
||||
|
||||
// ****************************************************************************
|
||||
// Guest Channel - Send
|
||||
// ====================
|
||||
GuestErrorT guest_channel_send(
|
||||
GuestChannelIdT channel_id, void* msg, int msg_size )
|
||||
{
|
||||
GuestChannelT* channel;
|
||||
ssize_t result;
|
||||
|
||||
channel = guest_channel_find(channel_id);
|
||||
if (NULL == channel)
|
||||
{
|
||||
DPRINTFE("Invalid channel identifier, channel_id=%i.", channel_id);
|
||||
return GUEST_FAILED;
|
||||
}
|
||||
|
||||
result = write(channel->sock, msg, msg_size);
|
||||
if (0 > result)
|
||||
{
|
||||
if (ENODEV == errno)
|
||||
{
|
||||
DPRINTFI("Channel %i on device %s disconnected.", channel_id,
|
||||
channel->dev_name);
|
||||
return GUEST_OKAY;
|
||||
} else {
|
||||
DPRINTFE("Failed to write to channel on device %s, error=%s.",
|
||||
channel->dev_name, strerror(errno));
|
||||
return GUEST_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
DPRINTFV("Sent message over channel on device %s.", channel->dev_name);
|
||||
return GUEST_OKAY;
|
||||
}
|
||||
// ****************************************************************************
|
||||
|
||||
// ****************************************************************************
|
||||
// Guest Channel - Receive
|
||||
// =======================
|
||||
GuestErrorT guest_channel_receive(
|
||||
GuestChannelIdT channel_id, char* msg_buf, int msg_buf_size,
|
||||
int* msg_size )
|
||||
{
|
||||
GuestChannelT* channel;
|
||||
ssize_t result;
|
||||
|
||||
channel = guest_channel_find(channel_id);
|
||||
if (NULL == channel)
|
||||
{
|
||||
DPRINTFE("Invalid channel identifier, channel_id=%i.", channel_id);
|
||||
return GUEST_FAILED;
|
||||
}
|
||||
|
||||
result = read(channel->sock, msg_buf, msg_buf_size);
|
||||
if (0 > result)
|
||||
{
|
||||
if (EINTR == errno)
|
||||
{
|
||||
DPRINTFD("Interrupted on socket read, error=%s.", strerror(errno));
|
||||
return GUEST_INTERRUPTED;
|
||||
|
||||
} else if (ENODEV == errno) {
|
||||
DPRINTFI("Channel %i on device %s disconnected.", channel_id,
|
||||
channel->dev_name);
|
||||
*msg_size = 0;
|
||||
return GUEST_OKAY;
|
||||
|
||||
} else {
|
||||
DPRINTFE("Failed to read from socket, error=%s.", strerror(errno));
|
||||
return GUEST_FAILED;
|
||||
}
|
||||
} else if (0 == result) {
|
||||
DPRINTFD("No message received from socket.");
|
||||
*msg_size = 0;
|
||||
return GUEST_OKAY;
|
||||
|
||||
} else {
|
||||
DPRINTFV("Received message, msg_size=%i.", result);
|
||||
*msg_size = result;
|
||||
}
|
||||
|
||||
return GUEST_OKAY;
|
||||
}
|
||||
// ****************************************************************************
|
||||
|
||||
// ****************************************************************************
|
||||
// Guest Channel - Open
|
||||
// ====================
|
||||
GuestErrorT guest_channel_open( char dev_name[], GuestChannelIdT* channel_id )
|
||||
{
|
||||
int fd;
|
||||
int result;
|
||||
struct stat stat_data;
|
||||
GuestChannelIdT empty_channel_id;
|
||||
GuestChannelT* channel;
|
||||
GuestErrorT error;
|
||||
|
||||
empty_channel_id = guest_channel_find_empty();
|
||||
if (GUEST_CHANNEL_ID_INVALID == empty_channel_id)
|
||||
{
|
||||
DPRINTFE("Allocation of channel failed, no free resources.");
|
||||
return GUEST_FAILED;
|
||||
}
|
||||
|
||||
channel = &(_channel[empty_channel_id]);
|
||||
memset(channel, 0, sizeof(GuestChannelT));
|
||||
|
||||
result = stat(dev_name, &stat_data);
|
||||
if (0 > result)
|
||||
{
|
||||
int err = errno;
|
||||
if (err == ENOENT)
|
||||
{
|
||||
DPRINTFI("Failed to stat, error=%s.", strerror(err));
|
||||
DPRINTFI("%s file does not exist, guest heartbeat not configured.",
|
||||
dev_name);
|
||||
return GUEST_NOT_CONFIGURED;
|
||||
}
|
||||
else {
|
||||
DPRINTFE("Failed to stat, error=%s.", strerror(err));
|
||||
return GUEST_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
if (S_ISCHR(stat_data.st_mode))
|
||||
{
|
||||
fd = open(dev_name, O_RDWR);
|
||||
if (0 > fd)
|
||||
{
|
||||
DPRINTFE("Failed to open device %s, error=%s.", dev_name,
|
||||
strerror(errno));
|
||||
return GUEST_FAILED;
|
||||
}
|
||||
|
||||
result = fcntl(fd, F_SETFD, FD_CLOEXEC);
|
||||
if (0 > result)
|
||||
{
|
||||
DPRINTFE("Failed to set to close on exec, error=%s.",
|
||||
strerror(errno));
|
||||
close(fd);
|
||||
return GUEST_FAILED;
|
||||
}
|
||||
|
||||
result = fcntl(fd, F_SETOWN, getpid());
|
||||
if (0 > result)
|
||||
{
|
||||
DPRINTFE("Failed to set socket ownership, error=%s.",
|
||||
strerror(errno));
|
||||
close(fd);
|
||||
return GUEST_FAILED;
|
||||
}
|
||||
|
||||
result = fcntl(fd, F_GETFL);
|
||||
if (0 > result)
|
||||
{
|
||||
DPRINTFE("Failed to get socket options, error=%s.",
|
||||
strerror(errno));
|
||||
close(fd);
|
||||
return GUEST_FAILED;
|
||||
}
|
||||
|
||||
result = fcntl(fd, F_SETFL, result | O_NONBLOCK | O_ASYNC);
|
||||
if (0 > result)
|
||||
{
|
||||
DPRINTFE("Failed to set socket options, error=%s.",
|
||||
strerror(errno));
|
||||
close(fd);
|
||||
return GUEST_FAILED;
|
||||
}
|
||||
|
||||
DPRINTFI("Opened character device %s", dev_name);
|
||||
|
||||
} else {
|
||||
error = guest_unix_open(&fd);
|
||||
if (GUEST_OKAY != error)
|
||||
{
|
||||
DPRINTFE("Failed to open unix socket %s, error=%s.",
|
||||
dev_name, guest_error_str(error));
|
||||
return error;
|
||||
}
|
||||
error = guest_unix_connect(fd, dev_name);
|
||||
if (GUEST_OKAY != error)
|
||||
{
|
||||
DPRINTFE("Failed to connect unix socket %s, error=%s.",
|
||||
dev_name, guest_error_str(error));
|
||||
close(fd);
|
||||
return error;
|
||||
}
|
||||
|
||||
DPRINTFI("Opened unix socket %s", dev_name);
|
||||
}
|
||||
|
||||
channel->inuse = true;
|
||||
snprintf(channel->dev_name, sizeof(channel->dev_name), "%s", dev_name);
|
||||
channel->char_device = S_ISCHR(stat_data.st_mode);
|
||||
channel->sock = fd;
|
||||
*channel_id = empty_channel_id;
|
||||
|
||||
DPRINTFD("Opened channel over device %s.", channel->dev_name);
|
||||
return GUEST_OKAY;
|
||||
}
|
||||
// ****************************************************************************
|
||||
|
||||
// ****************************************************************************
|
||||
// Guest Channel - Close
|
||||
// =====================
|
||||
GuestErrorT guest_channel_close( GuestChannelIdT channel_id )
|
||||
{
|
||||
GuestChannelT* channel;
|
||||
|
||||
channel = guest_channel_find(channel_id);
|
||||
if (NULL != channel)
|
||||
{
|
||||
if (channel->inuse)
|
||||
{
|
||||
if (0 <= channel->sock)
|
||||
close(channel->sock);
|
||||
|
||||
DPRINTFD("Closed channel over device %s.", channel->dev_name);
|
||||
memset(channel, 0, sizeof(GuestChannelT));
|
||||
}
|
||||
}
|
||||
|
||||
return GUEST_OKAY;
|
||||
}
|
||||
// ****************************************************************************
|
||||
|
||||
// ****************************************************************************
|
||||
// Guest Channel - Get Selection Object
|
||||
// ====================================
|
||||
int guest_channel_get_selobj( GuestChannelIdT channel_id )
|
||||
{
|
||||
GuestChannelT *channel;
|
||||
|
||||
channel = guest_channel_find(channel_id);
|
||||
if (NULL != channel)
|
||||
return channel->sock;
|
||||
|
||||
return -1;
|
||||
}
|
||||
// ****************************************************************************
|
||||
|
||||
// ****************************************************************************
|
||||
// Guest Channel - Initialize
|
||||
// ==========================
|
||||
GuestErrorT guest_channel_initialize( void )
|
||||
{
|
||||
memset(_channel, 0, sizeof(_channel));
|
||||
return GUEST_OKAY;
|
||||
}
|
||||
// ****************************************************************************
|
||||
|
||||
// ****************************************************************************
|
||||
// Guest Channel - Finalize
|
||||
// ========================
|
||||
GuestErrorT guest_channel_finalize( void )
|
||||
{
|
||||
memset(_channel, 0, sizeof(_channel));
|
||||
return GUEST_OKAY;
|
||||
}
|
||||
// ****************************************************************************
|
||||
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2016, Wind River Systems, Inc.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1) Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2) Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* 3) Neither the name of Wind River Systems nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software without specific
|
||||
* prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef __GUEST_CHANNEL_H__
|
||||
#define __GUEST_CHANNEL_H__
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "guest_limits.h"
|
||||
#include "guest_types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define GUEST_CHANNEL_ID_INVALID -1
|
||||
|
||||
typedef int GuestChannelIdT;
|
||||
|
||||
// ****************************************************************************
|
||||
// Guest Channel - Send
|
||||
// ====================
|
||||
extern GuestErrorT guest_channel_send(
|
||||
GuestChannelIdT channel_id, void* msg, int msg_size );
|
||||
// ****************************************************************************
|
||||
|
||||
// ****************************************************************************
|
||||
// Guest Channel - Receive
|
||||
// =======================
|
||||
extern GuestErrorT guest_channel_receive(
|
||||
GuestChannelIdT channel_id, char* msg_buf, int msg_buf_size,
|
||||
int* msg_size );
|
||||
// ****************************************************************************
|
||||
|
||||
// ****************************************************************************
|
||||
// Guest Channel - Open
|
||||
// ====================
|
||||
extern GuestErrorT guest_channel_open(
|
||||
char dev_name[], GuestChannelIdT* channel_id );
|
||||
// ****************************************************************************
|
||||
|
||||
// ****************************************************************************
|
||||
// Guest Channel - Close
|
||||
// =====================
|
||||
extern GuestErrorT guest_channel_close( GuestChannelIdT channel_id );
|
||||
// ****************************************************************************
|
||||
|
||||
// ****************************************************************************
|
||||
// Guest Channel - Get Selection Object
|
||||
// ====================================
|
||||
extern int guest_channel_get_selobj( GuestChannelIdT channel_id );
|
||||
// ****************************************************************************
|
||||
|
||||
// ****************************************************************************
|
||||
// Guest Channel - Initialize
|
||||
// ==========================
|
||||
extern GuestErrorT guest_channel_initialize( void );
|
||||
// ****************************************************************************
|
||||
|
||||
// ****************************************************************************
|
||||
// Guest Channel - Finalize
|
||||
// ========================
|
||||
extern GuestErrorT guest_channel_finalize( void );
|
||||
// ****************************************************************************
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __GUEST_CHANNEL_H__ */
|
||||
@@ -0,0 +1,312 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2016, Wind River Systems, Inc.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1) Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2) Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* 3) Neither the name of Wind River Systems nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software without specific
|
||||
* prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "guest_child_death.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <sys/eventfd.h>
|
||||
|
||||
#include "guest_limits.h"
|
||||
#include "guest_types.h"
|
||||
#include "guest_debug.h"
|
||||
#include "guest_selobj.h"
|
||||
|
||||
#define GUEST_CHILD_DEATH_MAX_DISPATCH 32
|
||||
|
||||
typedef struct {
|
||||
bool valid;
|
||||
pid_t pid;
|
||||
int exit_code;
|
||||
} GuestChildDeathInfoT;
|
||||
|
||||
typedef struct {
|
||||
bool valid;
|
||||
pid_t pid;
|
||||
GuestChildDeathCallbackT death_callback;
|
||||
} GuestChildDeathCallbackInfoT;
|
||||
|
||||
static int _child_death_fd = -1;
|
||||
static GuestChildDeathCallbackInfoT _callbacks[GUEST_CHILD_PROCESS_MAX];
|
||||
static GuestChildDeathInfoT _child_deaths[GUEST_CHILD_PROCESS_MAX];
|
||||
static uint64_t _child_death_count = 0;
|
||||
|
||||
// ****************************************************************************
|
||||
// Guest Child Death - Register
|
||||
// ============================
|
||||
GuestErrorT guest_child_death_register(
|
||||
pid_t pid, GuestChildDeathCallbackT callback )
|
||||
{
|
||||
GuestChildDeathCallbackInfoT* callback_info = NULL;
|
||||
|
||||
unsigned int callbacks_i;
|
||||
for (callbacks_i=0; GUEST_CHILD_PROCESS_MAX > callbacks_i; ++callbacks_i)
|
||||
{
|
||||
callback_info = &(_callbacks[callbacks_i]);
|
||||
|
||||
if (callback_info->valid)
|
||||
{
|
||||
if (pid == callback_info->pid)
|
||||
{
|
||||
callback_info->death_callback = callback;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
callback_info->valid = true;
|
||||
callback_info->pid = pid;
|
||||
callback_info->death_callback = callback;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (GUEST_CHILD_PROCESS_MAX <= callbacks_i)
|
||||
{
|
||||
DPRINTFE("Failed to register child death callback for pid (%i).",
|
||||
(int) pid);
|
||||
return GUEST_FAILED;
|
||||
}
|
||||
|
||||
return GUEST_OKAY;
|
||||
}
|
||||
// ****************************************************************************
|
||||
|
||||
// ****************************************************************************
|
||||
// Guest Child Death - Deregister
|
||||
// ==============================
|
||||
GuestErrorT guest_child_death_deregister( pid_t pid )
|
||||
{
|
||||
GuestChildDeathCallbackInfoT* callback_info = NULL;
|
||||
|
||||
unsigned int callbacks_i;
|
||||
for (callbacks_i=0; GUEST_CHILD_PROCESS_MAX > callbacks_i; ++callbacks_i)
|
||||
{
|
||||
callback_info = &(_callbacks[callbacks_i]);
|
||||
|
||||
if (!callback_info->valid)
|
||||
continue;
|
||||
|
||||
if (pid != callback_info->pid)
|
||||
continue;
|
||||
|
||||
callback_info->valid = 0;
|
||||
callback_info->pid = 0;
|
||||
callback_info->death_callback = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
return GUEST_OKAY;
|
||||
}
|
||||
// ****************************************************************************
|
||||
|
||||
// ****************************************************************************
|
||||
// Guest Child Death - Save
|
||||
// ========================
|
||||
GuestErrorT guest_child_death_save( pid_t pid, int exit_code )
|
||||
{
|
||||
uint64_t child_death_count = ++_child_death_count;
|
||||
GuestChildDeathInfoT* info = NULL;
|
||||
int result;
|
||||
|
||||
result = write(_child_death_fd, &child_death_count,
|
||||
sizeof(child_death_count));
|
||||
if (0 > result)
|
||||
DPRINTFE("Failed to signal child death, error=%s", strerror(errno));
|
||||
|
||||
DPRINTFD("Child process (%i) died.", (int) pid);
|
||||
|
||||
unsigned int death_i;
|
||||
for (death_i=0; GUEST_CHILD_PROCESS_MAX > death_i; ++death_i)
|
||||
{
|
||||
info = &(_child_deaths[death_i]);
|
||||
|
||||
if (info->valid)
|
||||
{
|
||||
if (pid == info->pid)
|
||||
{
|
||||
info->exit_code = exit_code;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
info->valid = true;
|
||||
info->pid = pid;
|
||||
info->exit_code = exit_code;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return GUEST_OKAY;
|
||||
}
|
||||
// ****************************************************************************
|
||||
|
||||
// ****************************************************************************
|
||||
// Guest Child Death - Dispatch
|
||||
// ============================
|
||||
static void guest_child_death_dispatch( int selobj )
|
||||
{
|
||||
static unsigned int _last_entry = 0;
|
||||
|
||||
uint64_t child_death_count;
|
||||
GuestChildDeathInfoT* info = NULL;
|
||||
GuestChildDeathCallbackInfoT* callback_info = NULL;
|
||||
unsigned int num_child_death_dispatched = 0;
|
||||
int result;
|
||||
|
||||
result = read(_child_death_fd, &child_death_count, sizeof(child_death_count));
|
||||
if (0 > result)
|
||||
{
|
||||
if (EINTR == errno)
|
||||
{
|
||||
DPRINTFD("Interrupted on read, error=%s.", strerror(errno));
|
||||
} else {
|
||||
DPRINTFE("Failed to dispatch, error=%s.", strerror(errno));
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int death_i;
|
||||
for( death_i=_last_entry; GUEST_CHILD_PROCESS_MAX > death_i; ++death_i )
|
||||
{
|
||||
info = &(_child_deaths[death_i]);
|
||||
|
||||
if (!info->valid)
|
||||
continue;
|
||||
|
||||
if (0 == info->pid)
|
||||
continue;
|
||||
|
||||
DPRINTFD("Child process (%i) exited with %i.", (int) info->pid,
|
||||
info->exit_code);
|
||||
|
||||
unsigned int callbacks_i;
|
||||
for (callbacks_i=0; GUEST_CHILD_PROCESS_MAX > callbacks_i; ++callbacks_i)
|
||||
{
|
||||
callback_info = &(_callbacks[callbacks_i]);
|
||||
|
||||
if (callback_info->valid)
|
||||
{
|
||||
if (info->pid == callback_info->pid)
|
||||
{
|
||||
if (NULL != callback_info->death_callback)
|
||||
{
|
||||
callback_info->death_callback(info->pid, info->exit_code);
|
||||
callback_info->valid = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
info->valid = false;
|
||||
|
||||
if (GUEST_CHILD_DEATH_MAX_DISPATCH <= ++num_child_death_dispatched)
|
||||
DPRINTFD("Maximum child process death dispatches (%i) reached.",
|
||||
GUEST_CHILD_DEATH_MAX_DISPATCH);
|
||||
}
|
||||
|
||||
if (GUEST_CHILD_PROCESS_MAX <= death_i)
|
||||
_last_entry = 0;
|
||||
else
|
||||
_last_entry = death_i;
|
||||
|
||||
// Check for outstanding child process deaths to handle.
|
||||
for (death_i=0; GUEST_CHILD_PROCESS_MAX > death_i; ++death_i)
|
||||
{
|
||||
info = &(_child_deaths[death_i]);
|
||||
|
||||
if (!info->valid)
|
||||
continue;
|
||||
|
||||
if (0 == info->pid)
|
||||
continue;
|
||||
|
||||
result = write(_child_death_fd, &child_death_count,
|
||||
sizeof(child_death_count));
|
||||
if (0 > result)
|
||||
DPRINTFE("Failed to signal child process death, error=%s",
|
||||
strerror(errno));
|
||||
break;
|
||||
}
|
||||
}
|
||||
// ****************************************************************************
|
||||
|
||||
// ****************************************************************************
|
||||
// Guest Child Death - Initialize
|
||||
// ==============================
|
||||
GuestErrorT guest_child_death_initialize( void )
|
||||
{
|
||||
GuestSelObjCallbacksT callbacks;
|
||||
GuestErrorT error;
|
||||
|
||||
_child_death_fd = eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK);
|
||||
if (0 > _child_death_fd)
|
||||
{
|
||||
DPRINTFE("Failed to open child death file descriptor,error=%s.",
|
||||
strerror(errno));
|
||||
return GUEST_FAILED;
|
||||
}
|
||||
|
||||
memset(&callbacks, 0, sizeof(callbacks));
|
||||
callbacks.read_callback = guest_child_death_dispatch;
|
||||
|
||||
error = guest_selobj_register(_child_death_fd, &callbacks);
|
||||
if (GUEST_OKAY != error)
|
||||
{
|
||||
DPRINTFE("Failed to register selection object, error=%s.",
|
||||
guest_error_str(error));
|
||||
close(_child_death_fd);
|
||||
_child_death_fd = -1;
|
||||
return error;
|
||||
}
|
||||
|
||||
return GUEST_OKAY;
|
||||
}
|
||||
// ****************************************************************************
|
||||
|
||||
// ****************************************************************************
|
||||
// Guest Child Death - Finalize
|
||||
// ============================
|
||||
GuestErrorT guest_child_death_finalize( void )
|
||||
{
|
||||
GuestErrorT error;
|
||||
|
||||
if (0 <= _child_death_fd)
|
||||
{
|
||||
error = guest_selobj_deregister(_child_death_fd);
|
||||
if (GUEST_OKAY != error)
|
||||
DPRINTFE("Failed to deregister selection object, error=%s.",
|
||||
guest_error_str(error));
|
||||
|
||||
close(_child_death_fd);
|
||||
_child_death_fd = -1;
|
||||
}
|
||||
|
||||
return GUEST_OKAY;
|
||||
}
|
||||
// ****************************************************************************
|
||||
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2016, Wind River Systems, Inc.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1) Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2) Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* 3) Neither the name of Wind River Systems nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software without specific
|
||||
* prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef __GUEST_CHILD_DEATH_H__
|
||||
#define __GUEST_CHILD_DEATH_H__
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "guest_types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define GUEST_CHILD_FAILED -65536
|
||||
|
||||
typedef void (*GuestChildDeathCallbackT) (pid_t pid, int exit_code);
|
||||
|
||||
// ****************************************************************************
|
||||
// Guest Child Death - Register
|
||||
// ============================
|
||||
extern GuestErrorT guest_child_death_register(
|
||||
pid_t pid, GuestChildDeathCallbackT callback );
|
||||
// ****************************************************************************
|
||||
|
||||
// ****************************************************************************
|
||||
// Guest Child Death - Deregister
|
||||
// ==============================
|
||||
extern GuestErrorT guest_child_death_deregister( pid_t pid );
|
||||
// ****************************************************************************
|
||||
|
||||
// ****************************************************************************
|
||||
// Guest Child Death - Save
|
||||
// ========================
|
||||
extern GuestErrorT guest_child_death_save( pid_t pid, int exit_code );
|
||||
// ****************************************************************************
|
||||
|
||||
// ****************************************************************************
|
||||
// Guest Child Death - Initialize
|
||||
// ==============================
|
||||
extern GuestErrorT guest_child_death_initialize( void );
|
||||
// ****************************************************************************
|
||||
|
||||
// ****************************************************************************
|
||||
// Guest Child Death - Finalize
|
||||
// ============================
|
||||
extern GuestErrorT guest_child_death_finalize( void );
|
||||
// ****************************************************************************
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __GUEST_CHILD_DEATH_H__ */
|
||||
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2016, Wind River Systems, Inc.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1) Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2) Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* 3) Neither the name of Wind River Systems nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software without specific
|
||||
* prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "guest_types.h"
|
||||
#include "guest_debug.h"
|
||||
#include "guest_process.h"
|
||||
|
||||
// ****************************************************************************
|
||||
// Guest Client - Main
|
||||
// ===================
|
||||
int main( int argc, char *argv[], char *envp[] )
|
||||
{
|
||||
GuestErrorT error;
|
||||
|
||||
error = guest_debug_initialize("Guest-Client");
|
||||
if (GUEST_OKAY != error)
|
||||
{
|
||||
printf("Debug initialization failed, error=%s.\n",
|
||||
guest_error_str(error));
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
error = guest_process_main(argc, argv, envp);
|
||||
if (GUEST_OKAY != error)
|
||||
{
|
||||
printf("Process failure, error=%s.\n", guest_error_str(error));
|
||||
return error;
|
||||
}
|
||||
|
||||
error = guest_debug_finalize();
|
||||
if (GUEST_OKAY != error)
|
||||
{
|
||||
printf("Debug finalization failed, error=%s.\n",
|
||||
guest_error_str(error));
|
||||
}
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
// ****************************************************************************
|
||||
@@ -0,0 +1,163 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2016, Wind River Systems, Inc.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1) Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2) Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* 3) Neither the name of Wind River Systems nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software without specific
|
||||
* prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "guest_config.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include "guest_types.h"
|
||||
#include "guest_debug.h"
|
||||
|
||||
#define GUEST_DEFAULT_COMM_DEVICE "/dev/vport1p1"
|
||||
|
||||
static GuestConfigT _config;
|
||||
|
||||
// ****************************************************************************
|
||||
// Guest Configuration - Get
|
||||
// =========================
|
||||
GuestConfigT* guest_config_get( void )
|
||||
{
|
||||
return &_config;
|
||||
}
|
||||
// ****************************************************************************
|
||||
|
||||
// ****************************************************************************
|
||||
// Guest Configuration - Show Usage
|
||||
// ================================
|
||||
void guest_config_show_usage( void )
|
||||
{
|
||||
printf("guest-client [ARGS]\n");
|
||||
printf(" where ARGS may be any of: \n");
|
||||
printf(" --name Override the name of the instance\n");
|
||||
printf(" --device Override default communication channel device\n");
|
||||
printf("\n");
|
||||
}
|
||||
// ****************************************************************************
|
||||
|
||||
// ****************************************************************************
|
||||
// Guest Configuration - Dump
|
||||
// ==========================
|
||||
static void guest_config_dump( void )
|
||||
{
|
||||
DPRINTFI("Guest-Client Configuration:");
|
||||
DPRINTFI(" name: %s", _config.name);
|
||||
DPRINTFI(" device: %s", _config.comm_device);
|
||||
}
|
||||
// ****************************************************************************
|
||||
|
||||
// ****************************************************************************
|
||||
// Guest Configuration - Parse Arguments
|
||||
// =====================================
|
||||
static GuestErrorT guest_config_parse_args( int argc, char *argv[] )
|
||||
{
|
||||
unsigned int arg_i;
|
||||
for (arg_i=1; arg_i < argc; ++arg_i)
|
||||
{
|
||||
if (0 == strcmp("--name", argv[arg_i]))
|
||||
{
|
||||
arg_i++;
|
||||
if (arg_i < argc)
|
||||
snprintf(_config.name, sizeof(_config.name), "%s", argv[arg_i]);
|
||||
|
||||
} else if (0 == strcmp("--device", argv[arg_i])) {
|
||||
arg_i++;
|
||||
if (arg_i < argc)
|
||||
snprintf(_config.comm_device, sizeof(_config.comm_device),
|
||||
"%s", argv[arg_i]);
|
||||
}
|
||||
}
|
||||
|
||||
return GUEST_OKAY;
|
||||
}
|
||||
// ****************************************************************************
|
||||
|
||||
// ****************************************************************************
|
||||
// Guest Configuration - Parse Environment
|
||||
// =======================================
|
||||
static GuestErrorT guest_config_parse_env( char *envp[] )
|
||||
{
|
||||
return GUEST_OKAY;
|
||||
}
|
||||
// ****************************************************************************
|
||||
|
||||
// ****************************************************************************
|
||||
// Guest Configuration - Initialize
|
||||
// ================================
|
||||
GuestErrorT guest_config_initialize( int argc, char *argv[], char *envp[] )
|
||||
{
|
||||
char name[GUEST_NAME_MAX_CHAR];
|
||||
GuestErrorT error;
|
||||
int result;
|
||||
|
||||
result = gethostname(name, sizeof(name));
|
||||
if (0 > result)
|
||||
{
|
||||
DPRINTFE("Failed to get hostname, error=%s.", strerror(errno));
|
||||
return GUEST_FAILED;
|
||||
}
|
||||
DPRINTFI("hostname=%s.", name);
|
||||
memset(&_config, 0, sizeof(GuestConfigT));
|
||||
snprintf(_config.name, sizeof(_config.name), "%s", name);
|
||||
snprintf(_config.comm_device, sizeof(_config.comm_device), "%s",
|
||||
GUEST_DEFAULT_COMM_DEVICE);
|
||||
|
||||
error = guest_config_parse_args(argc, argv);
|
||||
if (GUEST_OKAY != error)
|
||||
{
|
||||
DPRINTFE("Failed to parse arguments, error=%s.",
|
||||
guest_error_str(error));
|
||||
return error;
|
||||
}
|
||||
|
||||
error = guest_config_parse_env(envp);
|
||||
if (GUEST_OKAY != error)
|
||||
{
|
||||
DPRINTFE("Failed to parse environment, error=%s.",
|
||||
guest_error_str(error));
|
||||
return error;
|
||||
}
|
||||
|
||||
guest_config_dump();
|
||||
return GUEST_OKAY;
|
||||
}
|
||||
// ****************************************************************************
|
||||
|
||||
// ****************************************************************************
|
||||
// Guest Configuration - Finalize
|
||||
// ==============================
|
||||
GuestErrorT guest_config_finalize( void )
|
||||
{
|
||||
return GUEST_OKAY;
|
||||
}
|
||||
// ****************************************************************************
|
||||
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2016, Wind River Systems, Inc.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1) Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2) Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* 3) Neither the name of Wind River Systems nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software without specific
|
||||
* prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef __GUEST_CONFIGURATION_H__
|
||||
#define __GUEST_CONFIGURATION_H__
|
||||
|
||||
#include "guest_limits.h"
|
||||
#include "guest_types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
char name[GUEST_NAME_MAX_CHAR];
|
||||
char comm_device[GUEST_DEVICE_NAME_MAX_CHAR];
|
||||
} GuestConfigT;
|
||||
|
||||
// ****************************************************************************
|
||||
// Guest Configuration - Get
|
||||
// =========================
|
||||
extern GuestConfigT* guest_config_get( void );
|
||||
// ****************************************************************************
|
||||
|
||||
// ****************************************************************************
|
||||
// Guest Configuration - Show Usage
|
||||
// ================================
|
||||
extern void guest_config_show_usage( void );
|
||||
// ****************************************************************************
|
||||
|
||||
// ****************************************************************************
|
||||
// Guest Configuration - Initialize
|
||||
// ================================
|
||||
extern GuestErrorT guest_config_initialize(
|
||||
int argc, char *argv[], char *envp[] );
|
||||
// ****************************************************************************
|
||||
|
||||
// ****************************************************************************
|
||||
// Guest Configuration - Finalize
|
||||
// ==============================
|
||||
extern GuestErrorT guest_config_finalize( void );
|
||||
// ****************************************************************************
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __GUEST_CONFIGURATION_H__ */
|
||||
@@ -0,0 +1,146 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2016, Wind River Systems, Inc.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1) Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2) Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* 3) Neither the name of Wind River Systems nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software without specific
|
||||
* prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "guest_debug.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "guest_types.h"
|
||||
|
||||
#define GUEST_DEBUG_WANT_SYSLOG
|
||||
#ifdef GUEST_DEBUG_WANT_SYSLOG
|
||||
#include <syslog.h>
|
||||
#endif
|
||||
|
||||
static char _process_name[30];
|
||||
static GuestDebugLogLevelT _log_level = GUEST_DEBUG_LOG_LEVEL_INFO;
|
||||
|
||||
// ****************************************************************************
|
||||
// Guest Debug - Log Level String
|
||||
// ==============================
|
||||
const char* guest_debug_log_level_str( GuestDebugLogLevelT level )
|
||||
{
|
||||
switch (level) {
|
||||
case GUEST_DEBUG_LOG_LEVEL_ERROR: return "error";
|
||||
case GUEST_DEBUG_LOG_LEVEL_INFO: return " info";
|
||||
case GUEST_DEBUG_LOG_LEVEL_DEBUG: return "debug";
|
||||
case GUEST_DEBUG_LOG_LEVEL_VERBOSE: return " verb";
|
||||
default:
|
||||
return "???";
|
||||
}
|
||||
}
|
||||
// ****************************************************************************
|
||||
|
||||
// ****************************************************************************
|
||||
// Guest Debug - Set Log Level
|
||||
// ===========================
|
||||
void guest_debug_set_log_level( GuestDebugLogLevelT level )
|
||||
{
|
||||
_log_level = level;
|
||||
}
|
||||
// ****************************************************************************
|
||||
|
||||
// ****************************************************************************
|
||||
// Guest Debug - Want Log
|
||||
// ======================
|
||||
bool guest_debug_want_log( GuestDebugLogLevelT level )
|
||||
{
|
||||
return (level <= _log_level);
|
||||
}
|
||||
// ****************************************************************************
|
||||
|
||||
// ****************************************************************************
|
||||
// Guest Debug - Log
|
||||
// =================
|
||||
void guest_debug_log( const char* format, ... )
|
||||
{
|
||||
char time_str[80];
|
||||
char date_str[32];
|
||||
struct tm t_real;
|
||||
struct timespec ts_real;
|
||||
va_list arguments;
|
||||
char log_data[512];
|
||||
|
||||
va_start(arguments, format);
|
||||
vsnprintf(log_data, sizeof(log_data), format, arguments);
|
||||
va_end(arguments);
|
||||
|
||||
clock_gettime(CLOCK_REALTIME, &ts_real);
|
||||
|
||||
if (NULL == localtime_r(&(ts_real.tv_sec), &t_real))
|
||||
{
|
||||
snprintf( time_str, sizeof(time_str),
|
||||
"YYYY:MM:DD HH:MM:SS.xxx" );
|
||||
} else {
|
||||
strftime( date_str, sizeof(date_str), "%b %e %H:%M:%S",
|
||||
&t_real );
|
||||
snprintf( time_str, sizeof(time_str), "%s.%03ld", date_str,
|
||||
ts_real.tv_nsec/1000000 );
|
||||
}
|
||||
|
||||
#ifdef GUEST_DEBUG_WANT_SYSLOG
|
||||
syslog(LOG_DEBUG, "%s", log_data);
|
||||
#else
|
||||
printf("%s %s: %s\n", time_str, _process_name, log_data);
|
||||
#endif
|
||||
}
|
||||
// ****************************************************************************
|
||||
|
||||
// ****************************************************************************
|
||||
// Guest Debug - Initialize
|
||||
// ========================
|
||||
GuestErrorT guest_debug_initialize( char process_name[] )
|
||||
{
|
||||
_log_level = GUEST_DEBUG_LOG_LEVEL_INFO;
|
||||
snprintf(_process_name, sizeof(_process_name), "%s", process_name);
|
||||
|
||||
#ifdef GUEST_DEBUG_WANT_SYSLOG
|
||||
openlog(_process_name, LOG_PID | LOG_NDELAY, LOG_DAEMON);
|
||||
#endif
|
||||
|
||||
return GUEST_OKAY;
|
||||
}
|
||||
// ****************************************************************************
|
||||
|
||||
// ****************************************************************************
|
||||
// Guest Debug - Finalize
|
||||
// ======================
|
||||
GuestErrorT guest_debug_finalize( void )
|
||||
{
|
||||
_log_level = GUEST_DEBUG_LOG_LEVEL_INFO;
|
||||
_process_name[0] = '\0';
|
||||
|
||||
#ifdef GUEST_DEBUG_WANT_SYSLOG
|
||||
closelog();
|
||||
#endif
|
||||
|
||||
return GUEST_OKAY;
|
||||
}
|
||||
// ****************************************************************************
|
||||
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2016, Wind River Systems, Inc.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1) Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2) Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* 3) Neither the name of Wind River Systems nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software without specific
|
||||
* prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef __GUEST_DEBUG_H__
|
||||
#define __GUEST_DEBUG_H__
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "guest_types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
GUEST_DEBUG_LOG_LEVEL_ERROR,
|
||||
GUEST_DEBUG_LOG_LEVEL_INFO,
|
||||
GUEST_DEBUG_LOG_LEVEL_DEBUG,
|
||||
GUEST_DEBUG_LOG_LEVEL_VERBOSE,
|
||||
} GuestDebugLogLevelT;
|
||||
|
||||
#define DPRINTF(level, format, args...) \
|
||||
if (guest_debug_want_log(level)) \
|
||||
guest_debug_log("%s: %s(%i): " format, \
|
||||
guest_debug_log_level_str(level), \
|
||||
__FILE__, __LINE__, ##args)
|
||||
|
||||
#define DPRINTFE(format, args...) \
|
||||
DPRINTF(GUEST_DEBUG_LOG_LEVEL_ERROR, format, ##args)
|
||||
#define DPRINTFI(format, args...) \
|
||||
DPRINTF(GUEST_DEBUG_LOG_LEVEL_INFO, format, ##args)
|
||||
#define DPRINTFD(format, args...) \
|
||||
DPRINTF(GUEST_DEBUG_LOG_LEVEL_DEBUG, format, ##args)
|
||||
#define DPRINTFV(format, args... ) \
|
||||
DPRINTF(GUEST_DEBUG_LOG_LEVEL_VERBOSE, format, ##args)
|
||||
|
||||
// ****************************************************************************
|
||||
// Guest Debug - Log Level String
|
||||
// ==============================
|
||||
extern const char* guest_debug_log_level_str( GuestDebugLogLevelT level );
|
||||
// ****************************************************************************
|
||||
|
||||
// ****************************************************************************
|
||||
// Guest Debug - Set Log Level
|
||||
// ===========================
|
||||
extern void guest_debug_set_log_level( GuestDebugLogLevelT level );
|
||||
// ****************************************************************************
|
||||
|
||||
// ****************************************************************************
|
||||
// Guest Debug - Want Log
|
||||
// ======================
|
||||
extern bool guest_debug_want_log( GuestDebugLogLevelT level );
|
||||
// ****************************************************************************
|
||||
|
||||
// ****************************************************************************
|
||||
// Guest Debug - Log
|
||||
// =================
|
||||
extern void guest_debug_log( const char* format, ... );
|
||||
// ****************************************************************************
|
||||
|
||||
// ****************************************************************************
|
||||
// Guest Debug - Initialize
|
||||
// ========================
|
||||
extern GuestErrorT guest_debug_initialize( char process_name[] );
|
||||
// ****************************************************************************
|
||||
|
||||
// ****************************************************************************
|
||||
// Guest Debug - Finalize
|
||||
// ======================
|
||||
extern GuestErrorT guest_debug_finalize( void );
|
||||
// ****************************************************************************
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __GUEST_DEBUG_H__ */
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2016, Wind River Systems, Inc.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1) Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2) Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* 3) Neither the name of Wind River Systems nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software without specific
|
||||
* prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef __GUEST_LIMITS_H__
|
||||
#define __GUEST_LIMITS_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define GUEST_NAME_MAX_CHAR 64
|
||||
#define GUEST_DEVICE_NAME_MAX_CHAR 255
|
||||
#define GUEST_MIN_TICK_INTERVAL_IN_MS 25
|
||||
#define GUEST_TICK_INTERVAL_IN_MS 300
|
||||
#define GUEST_SCHEDULING_MAX_DELAY_IN_MS 800
|
||||
#define GUEST_SCHEDULING_DELAY_DEBOUNCE_IN_MS 2000
|
||||
#define GUEST_TIMERS_MAX 128
|
||||
#define GUEST_MAX_TIMERS_PER_TICK GUEST_TIMERS_MAX / 4
|
||||
#define GUEST_SELECT_OBJS_MAX 128
|
||||
#define GUEST_MAX_SIGNALS 32
|
||||
#define GUEST_MAX_CONNECTIONS 32
|
||||
#define GUEST_CHILD_PROCESS_MAX 16
|
||||
#define GUEST_APPLICATIONS_MAX 16
|
||||
#define GUEST_HEARTBEAT_MIN_INTERVAL_MS 400
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __GUEST_LIMITS_H__ */
|
||||
@@ -0,0 +1,375 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2016, Wind River Systems, Inc.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1) Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2) Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* 3) Neither the name of Wind River Systems nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software without specific
|
||||
* prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "guest_process.h"
|
||||
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
#include "guest_limits.h"
|
||||
#include "guest_types.h"
|
||||
#include "guest_debug.h"
|
||||
#include "guest_signal.h"
|
||||
#include "guest_config.h"
|
||||
#include "guest_selobj.h"
|
||||
#include "guest_timer.h"
|
||||
#include "guest_channel.h"
|
||||
#include "guest_stream.h"
|
||||
#include "guest_unix.h"
|
||||
#include "guest_script.h"
|
||||
#include "guest_heartbeat.h"
|
||||
#include "guest_child_death.h"
|
||||
|
||||
static sig_atomic_t _stay_on = 1;
|
||||
static sig_atomic_t _reload = 0;
|
||||
static sig_atomic_t _reap_children = 0;
|
||||
|
||||
// ****************************************************************************
|
||||
// Guest Process - Reload
|
||||
// ======================
|
||||
static void guest_process_reload( void )
|
||||
{
|
||||
int result;
|
||||
|
||||
DPRINTFI("Reload signal handled.");
|
||||
_reload = 0;
|
||||
|
||||
result = access("/tmp/guest_debug_debug", F_OK);
|
||||
if (0 == result)
|
||||
{
|
||||
DPRINTFI("Debug log level set to debug.");
|
||||
guest_debug_set_log_level(GUEST_DEBUG_LOG_LEVEL_DEBUG);
|
||||
return;
|
||||
}
|
||||
|
||||
result = access("/tmp/guest_debug_verbose", F_OK);
|
||||
if (0 == result)
|
||||
{
|
||||
DPRINTFI("Debug log level set to verbose.");
|
||||
guest_debug_set_log_level(GUEST_DEBUG_LOG_LEVEL_VERBOSE);
|
||||
return;
|
||||
}
|
||||
|
||||
DPRINTFI("Debug log level set to info.");
|
||||
guest_debug_set_log_level(GUEST_DEBUG_LOG_LEVEL_INFO);
|
||||
}
|
||||
// ****************************************************************************
|
||||
|
||||
// ****************************************************************************
|
||||
// Guest Process - Reap Children
|
||||
// =============================
|
||||
static void guest_process_reap_children( void )
|
||||
{
|
||||
pid_t pid;
|
||||
int status;
|
||||
|
||||
if (_reap_children)
|
||||
{
|
||||
_reap_children = 0;
|
||||
|
||||
while (0 < (pid = waitpid(-1, &status, WNOHANG | WUNTRACED)))
|
||||
{
|
||||
if (WIFEXITED(status))
|
||||
guest_child_death_save(pid, WEXITSTATUS(status));
|
||||
else
|
||||
guest_child_death_save(pid, GUEST_CHILD_FAILED);
|
||||
}
|
||||
}
|
||||
}
|
||||
// ****************************************************************************
|
||||
|
||||
// ****************************************************************************
|
||||
// Guest Process - Signal Handler
|
||||
// ==============================
|
||||
static void guest_process_signal_handler( int signum )
|
||||
{
|
||||
switch (signum)
|
||||
{
|
||||
case SIGINT:
|
||||
case SIGTERM:
|
||||
case SIGQUIT:
|
||||
_stay_on = 0;
|
||||
break;
|
||||
|
||||
case SIGHUP:
|
||||
_reload = 1;
|
||||
break;
|
||||
|
||||
case SIGCHLD:
|
||||
_reap_children = 1;
|
||||
break;
|
||||
|
||||
case SIGCONT:
|
||||
DPRINTFD("Ignoring signal SIGCONT (%i).", signum);
|
||||
break;
|
||||
|
||||
case SIGPIPE:
|
||||
DPRINTFD("Ignoring signal SIGPIPE (%i).", signum);
|
||||
break;
|
||||
|
||||
default:
|
||||
DPRINTFD("Signal (%i) ignored.", signum);
|
||||
break;
|
||||
}
|
||||
}
|
||||
// ****************************************************************************
|
||||
|
||||
// ****************************************************************************
|
||||
// Guest Process - Initialize
|
||||
// ==========================
|
||||
static GuestErrorT guest_process_initialize(
|
||||
int argc, char *argv[], char *envp[] )
|
||||
{
|
||||
GuestConfigT* config = NULL;
|
||||
GuestErrorT error;
|
||||
|
||||
error = guest_config_initialize(argc, argv, envp);
|
||||
if (GUEST_OKAY != error)
|
||||
{
|
||||
DPRINTFE("Failed to initialize configuration module, error=%s.",
|
||||
guest_error_str(error));
|
||||
guest_config_show_usage();
|
||||
return error;
|
||||
}
|
||||
|
||||
error = guest_selobj_initialize();
|
||||
if (GUEST_OKAY != error)
|
||||
{
|
||||
DPRINTFE("Failed to initialize selection object module, error=%s.",
|
||||
guest_error_str(error));
|
||||
return GUEST_FAILED;
|
||||
}
|
||||
|
||||
error = guest_timer_initialize();
|
||||
if (GUEST_OKAY != error)
|
||||
{
|
||||
DPRINTFE("Failed to initialize timer module, error=%s.",
|
||||
guest_error_str(error));
|
||||
return GUEST_FAILED;
|
||||
}
|
||||
|
||||
error = guest_child_death_initialize();
|
||||
if (GUEST_OKAY != error)
|
||||
{
|
||||
DPRINTFE("Failed to initialize child death module, error=%s.",
|
||||
guest_error_str(error));
|
||||
return GUEST_FAILED;
|
||||
}
|
||||
|
||||
error = guest_unix_initialize();
|
||||
if (GUEST_OKAY != error)
|
||||
{
|
||||
DPRINTFE("Failed to initialize unix module, error=%s.",
|
||||
guest_error_str(error));
|
||||
return GUEST_FAILED;
|
||||
}
|
||||
|
||||
error = guest_channel_initialize();
|
||||
if (GUEST_OKAY != error)
|
||||
{
|
||||
DPRINTFE("Failed to initialize channel module, error=%s.",
|
||||
guest_error_str(error));
|
||||
return GUEST_FAILED;
|
||||
}
|
||||
|
||||
error = guest_stream_initialize();
|
||||
if (GUEST_OKAY != error)
|
||||
{
|
||||
DPRINTFE("Failed to initialize stream module, error=%s.",
|
||||
guest_error_str(error));
|
||||
return GUEST_FAILED;
|
||||
}
|
||||
|
||||
error = guest_script_initialize();
|
||||
if (GUEST_OKAY != error)
|
||||
{
|
||||
DPRINTFE("Failed to initialize script module, error=%s.",
|
||||
guest_error_str(error));
|
||||
return GUEST_FAILED;
|
||||
}
|
||||
|
||||
config = guest_config_get();
|
||||
|
||||
error = guest_heartbeat_initialize(config->comm_device);
|
||||
if (GUEST_OKAY != error)
|
||||
{
|
||||
DPRINTFE("Failed to initialize heartbeat module, error=%s.",
|
||||
guest_error_str(error));
|
||||
return error;
|
||||
}
|
||||
|
||||
return GUEST_OKAY;
|
||||
}
|
||||
// ****************************************************************************
|
||||
|
||||
// ****************************************************************************
|
||||
// Guest Process - Finalize
|
||||
// ========================
|
||||
static GuestErrorT guest_process_finalize( void )
|
||||
{
|
||||
GuestErrorT error;
|
||||
|
||||
error = guest_heartbeat_finalize();
|
||||
if (GUEST_OKAY != error)
|
||||
{
|
||||
DPRINTFE("Failed to finalize heartbeat module, error=%s.",
|
||||
guest_error_str(error));
|
||||
}
|
||||
|
||||
error = guest_script_finalize();
|
||||
if (GUEST_OKAY != error)
|
||||
{
|
||||
DPRINTFE("Failed to finalize script module, error=%s.",
|
||||
guest_error_str(error));
|
||||
}
|
||||
|
||||
error = guest_stream_finalize();
|
||||
if (GUEST_OKAY != error)
|
||||
{
|
||||
DPRINTFE("Failed to finalize stream module, error=%s.",
|
||||
guest_error_str(error));
|
||||
}
|
||||
|
||||
error = guest_channel_finalize();
|
||||
if (GUEST_OKAY != error)
|
||||
{
|
||||
DPRINTFE("Failed to finalize channel module, error=%s.",
|
||||
guest_error_str(error));
|
||||
}
|
||||
|
||||
error = guest_unix_finalize();
|
||||
if (GUEST_OKAY != error)
|
||||
{
|
||||
DPRINTFE("Failed to finalize unix module, error=%s.",
|
||||
guest_error_str(error));
|
||||
}
|
||||
|
||||
error = guest_child_death_finalize();
|
||||
if (GUEST_OKAY != error)
|
||||
{
|
||||
DPRINTFE("Failed to finalize child death module, error=%s.",
|
||||
guest_error_str(error));
|
||||
}
|
||||
|
||||
error = guest_timer_finalize();
|
||||
if (GUEST_OKAY != error)
|
||||
{
|
||||
DPRINTFE("Failed to finalize timer module, error=%s.",
|
||||
guest_error_str(error));
|
||||
}
|
||||
|
||||
error = guest_selobj_finalize();
|
||||
if (GUEST_OKAY != error)
|
||||
{
|
||||
DPRINTFE("Failed to finialize selection object module, error=%s.",
|
||||
guest_error_str(error));
|
||||
}
|
||||
|
||||
error = guest_config_finalize();
|
||||
if (GUEST_OKAY != error)
|
||||
{
|
||||
DPRINTFE("Failed to finialize configuration module, error=%s.",
|
||||
guest_error_str(error));
|
||||
}
|
||||
|
||||
return GUEST_OKAY;
|
||||
}
|
||||
// ****************************************************************************
|
||||
|
||||
// ****************************************************************************
|
||||
// Guest Process - Main
|
||||
// ====================
|
||||
GuestErrorT guest_process_main( int argc, char *argv[], char *envp[] )
|
||||
{
|
||||
unsigned int next_interval_in_ms;
|
||||
GuestErrorT error;
|
||||
|
||||
DPRINTFI("Starting.");
|
||||
|
||||
guest_signal_register_handler(SIGINT, guest_process_signal_handler);
|
||||
guest_signal_register_handler(SIGTERM, guest_process_signal_handler);
|
||||
guest_signal_register_handler(SIGQUIT, guest_process_signal_handler);
|
||||
guest_signal_register_handler(SIGHUP, guest_process_signal_handler);
|
||||
guest_signal_register_handler(SIGCHLD, guest_process_signal_handler);
|
||||
guest_signal_register_handler(SIGCONT, guest_process_signal_handler);
|
||||
guest_signal_register_handler(SIGPIPE, guest_process_signal_handler);
|
||||
guest_signal_ignore(SIGIO);
|
||||
|
||||
error = guest_process_initialize(argc, argv, envp);
|
||||
if (GUEST_OKAY != error)
|
||||
{
|
||||
if (error != GUEST_NOT_CONFIGURED)
|
||||
{
|
||||
DPRINTFE("Failed initialize process restarting in 20 seconds,"
|
||||
"error=%s.", guest_error_str(error));
|
||||
sleep(20);
|
||||
}
|
||||
else {
|
||||
DPRINTFI("Application is not configured, will be not restarted,"
|
||||
" exit code=%s", guest_error_str(error));
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
DPRINTFI("Started.");
|
||||
|
||||
while (_stay_on)
|
||||
{
|
||||
next_interval_in_ms = guest_timer_schedule();
|
||||
|
||||
error = guest_selobj_dispatch(next_interval_in_ms);
|
||||
if (GUEST_OKAY != error)
|
||||
{
|
||||
DPRINTFE("Selection object dispatch failed, error=%s.",
|
||||
guest_error_str(error));
|
||||
break;
|
||||
}
|
||||
|
||||
guest_process_reap_children();
|
||||
|
||||
if (_reload)
|
||||
guest_process_reload();
|
||||
}
|
||||
|
||||
DPRINTFI("Shutting down.");
|
||||
|
||||
error = guest_process_finalize();
|
||||
if (GUEST_OKAY != error)
|
||||
{
|
||||
DPRINTFE("Failed finalize process, error=%s.",
|
||||
guest_error_str(error) );
|
||||
}
|
||||
|
||||
DPRINTFI("Shutdown complete.");
|
||||
|
||||
return GUEST_OKAY;
|
||||
}
|
||||
// ****************************************************************************
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2016, Wind River Systems, Inc.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1) Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2) Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* 3) Neither the name of Wind River Systems nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software without specific
|
||||
* prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef __GUEST_PROCESS_H__
|
||||
#define __GUEST_PROCESS_H__
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "guest_types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// ****************************************************************************
|
||||
// Guest Process - Main
|
||||
// ====================
|
||||
extern GuestErrorT guest_process_main( int argc, char *argv[], char *envp[] );
|
||||
// ****************************************************************************
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __GUEST_PROCESS_H__ */
|
||||
@@ -0,0 +1,410 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2016, Wind River Systems, Inc.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1) Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2) Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* 3) Neither the name of Wind River Systems nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software without specific
|
||||
* prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "guest_script.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/resource.h>
|
||||
|
||||
#include "guest_limits.h"
|
||||
#include "guest_types.h"
|
||||
#include "guest_debug.h"
|
||||
#include "guest_selobj.h"
|
||||
#include "guest_utils.h"
|
||||
#include "guest_child_death.h"
|
||||
|
||||
#define GUEST_SCRIPT_SETUP_FAILURE -65535
|
||||
|
||||
typedef struct {
|
||||
bool inuse;
|
||||
int pid;
|
||||
int fd;
|
||||
int log_end_ptr;
|
||||
char log_msg[256];
|
||||
GuestScriptIdT script_id;
|
||||
GuestScriptCallbackT callback;
|
||||
} GuestScriptDataT;
|
||||
|
||||
static GuestScriptDataT _scripts[GUEST_CHILD_PROCESS_MAX];
|
||||
|
||||
// ****************************************************************************
|
||||
// Guest Script - Abort
|
||||
// ====================
|
||||
void guest_script_abort( GuestScriptIdT script_id )
|
||||
{
|
||||
int result;
|
||||
GuestScriptDataT* entry;
|
||||
GuestErrorT error;
|
||||
|
||||
if (GUEST_SCRIPT_ID_INVALID == script_id)
|
||||
return;
|
||||
|
||||
if (GUEST_CHILD_PROCESS_MAX <= script_id)
|
||||
return;
|
||||
|
||||
entry = &(_scripts[script_id]);
|
||||
|
||||
if (entry->inuse)
|
||||
{
|
||||
if (-1 != entry->pid)
|
||||
{
|
||||
error = guest_child_death_deregister(entry->pid);
|
||||
if (GUEST_OKAY != error)
|
||||
{
|
||||
DPRINTFE("Failed to deregister for child death %i, error=%s.",
|
||||
entry->pid, guest_error_str(error));
|
||||
}
|
||||
|
||||
result = kill(entry->pid, SIGKILL);
|
||||
if (0 > result)
|
||||
{
|
||||
if (ESRCH == errno)
|
||||
{
|
||||
DPRINTFV("Script pid (%i) not running.", entry->pid);
|
||||
} else {
|
||||
DPRINTFE("Failed to send kill signal to script pid %i, "
|
||||
"error=%s.", entry->pid, strerror(errno));
|
||||
}
|
||||
} else {
|
||||
DPRINTFD("Script pid (%i) killed.", entry->pid);
|
||||
}
|
||||
}
|
||||
|
||||
if (-1 != entry->fd)
|
||||
{
|
||||
error = guest_selobj_deregister(entry->fd);
|
||||
if (GUEST_OKAY != error)
|
||||
{
|
||||
DPRINTFE("Failed to deregister selection object %i, error=%s.",
|
||||
entry->fd, guest_error_str(error));
|
||||
}
|
||||
|
||||
close(entry->fd);
|
||||
}
|
||||
|
||||
memset(entry, 0, sizeof(GuestScriptDataT));
|
||||
entry->pid = -1;
|
||||
entry->fd = -1;
|
||||
entry->script_id = GUEST_SCRIPT_ID_INVALID;
|
||||
}
|
||||
}
|
||||
// ****************************************************************************
|
||||
|
||||
// ****************************************************************************
|
||||
// Guest Script - Dispatch
|
||||
// =======================
|
||||
static void guest_script_dispatch( int selobj )
|
||||
{
|
||||
int bytes_avail;
|
||||
int result;
|
||||
GuestScriptDataT* entry;
|
||||
|
||||
unsigned int script_i;
|
||||
for (script_i=0; GUEST_CHILD_PROCESS_MAX > script_i; ++script_i)
|
||||
{
|
||||
entry = &(_scripts[script_i]);
|
||||
if (entry->inuse)
|
||||
if (selobj == entry->fd)
|
||||
break;
|
||||
}
|
||||
|
||||
if (GUEST_CHILD_PROCESS_MAX <= script_i)
|
||||
return;
|
||||
|
||||
bytes_avail = sizeof(entry->log_msg) - entry->log_end_ptr;
|
||||
|
||||
result = read(selobj, &(entry->log_msg[entry->log_end_ptr]), bytes_avail);
|
||||
if (0 > result)
|
||||
{
|
||||
if (EINTR == errno) {
|
||||
DPRINTFD("Interrupted on read, error=%s.", strerror(errno));
|
||||
return;
|
||||
|
||||
} else {
|
||||
DPRINTFE("Failed to read, error=%s.", strerror(errno));
|
||||
return;
|
||||
}
|
||||
} else if (0 == result) {
|
||||
DPRINTFD("No message received.");
|
||||
return;
|
||||
|
||||
} else {
|
||||
DPRINTFD("Received message, msg_size=%i.", result);
|
||||
entry->log_end_ptr += result;
|
||||
}
|
||||
}
|
||||
// ****************************************************************************
|
||||
|
||||
// ****************************************************************************
|
||||
// Guest Script - Callback
|
||||
// =======================
|
||||
static void guest_script_callback( pid_t pid, int exit_code )
|
||||
{
|
||||
GuestScriptDataT* entry;
|
||||
|
||||
unsigned int script_i;
|
||||
for (script_i=0; GUEST_CHILD_PROCESS_MAX > script_i; ++script_i)
|
||||
{
|
||||
entry = &(_scripts[script_i]);
|
||||
if (entry->inuse)
|
||||
if ((int) pid == entry->pid)
|
||||
break;
|
||||
}
|
||||
|
||||
if (GUEST_CHILD_PROCESS_MAX <= script_i)
|
||||
return;
|
||||
|
||||
DPRINTFD("PID %i exited with %i", (int) pid, exit_code);
|
||||
|
||||
if (NULL != entry->callback)
|
||||
entry->callback(entry->script_id, exit_code, entry->log_msg);
|
||||
|
||||
guest_script_abort(entry->script_id);
|
||||
}
|
||||
// ****************************************************************************
|
||||
|
||||
// ****************************************************************************
|
||||
// Guest Script - Invoke
|
||||
// =====================
|
||||
GuestErrorT guest_script_invoke(
|
||||
char script[], char* script_argv[], GuestScriptCallbackT callback,
|
||||
GuestScriptIdT* script_id )
|
||||
{
|
||||
int fd[2];
|
||||
pid_t pid;
|
||||
struct stat stat_data;
|
||||
char* script_name = guest_utils_basename(script);
|
||||
char* script_exec = script;
|
||||
int result;
|
||||
GuestScriptDataT* entry;
|
||||
GuestSelObjCallbacksT callbacks;
|
||||
GuestErrorT error;
|
||||
|
||||
*script_id = GUEST_SCRIPT_ID_INVALID;
|
||||
|
||||
unsigned int script_i;
|
||||
for (script_i=1; GUEST_CHILD_PROCESS_MAX > script_i; ++script_i)
|
||||
{
|
||||
entry = &(_scripts[script_i]);
|
||||
if (!entry->inuse)
|
||||
break;
|
||||
}
|
||||
|
||||
if (GUEST_CHILD_PROCESS_MAX <= script_i)
|
||||
{
|
||||
DPRINTFE("Failed to allocate script data.");
|
||||
return GUEST_FAILED;
|
||||
}
|
||||
|
||||
memset(entry, 0, sizeof(GuestScriptDataT));
|
||||
entry->script_id = script_i;
|
||||
entry->callback = callback;
|
||||
entry->pid = -1;
|
||||
entry->fd = -1;
|
||||
|
||||
result = access(script_exec, F_OK | X_OK);
|
||||
if (0 > result)
|
||||
{
|
||||
DPRINTFE("Script %s access failed, error=%s.", script_exec,
|
||||
strerror(errno));
|
||||
return GUEST_FAILED;
|
||||
}
|
||||
|
||||
result = stat(script_exec, &stat_data);
|
||||
if (0 > result)
|
||||
{
|
||||
DPRINTFE("Script %s stat failed, error=%s.", script_exec,
|
||||
strerror( errno ) );
|
||||
return GUEST_FAILED;
|
||||
}
|
||||
|
||||
if (0 >= stat_data.st_size)
|
||||
{
|
||||
DPRINTFE("Script %s has zero size.", script_exec);
|
||||
return GUEST_FAILED;
|
||||
}
|
||||
|
||||
result = pipe(fd);
|
||||
if (0 > result)
|
||||
{
|
||||
DPRINTFE("Script %s pipe creation failed, error=%s.", script_exec,
|
||||
strerror(errno));
|
||||
return GUEST_FAILED;
|
||||
}
|
||||
|
||||
result = fcntl(fd[0], F_SETFL, O_NONBLOCK);
|
||||
if (0 > result)
|
||||
{
|
||||
DPRINTFE("Script %s pipe failed to make read end non-blocking, "
|
||||
"error=%s.", script_exec, strerror(errno));
|
||||
close(fd[0]);
|
||||
close(fd[1]);
|
||||
return GUEST_FAILED;
|
||||
}
|
||||
|
||||
pid = fork();
|
||||
if (0 > pid)
|
||||
{
|
||||
DPRINTFE("Failed to fork process for script %s, error=%s.",
|
||||
script_exec, strerror(errno));
|
||||
close(fd[0]);
|
||||
close(fd[1]);
|
||||
return GUEST_FAILED;
|
||||
|
||||
} else if (0 == pid) {
|
||||
// Child process.
|
||||
struct rlimit file_limits;
|
||||
|
||||
close(fd[0]); // close read end of pipe
|
||||
|
||||
result = setpgid(0, 0);
|
||||
if (0 > result)
|
||||
{
|
||||
DPRINTFE("Failed to set process group id for script %s, "
|
||||
"error=%s.", script_exec, strerror( errno ) );
|
||||
exit(GUEST_SCRIPT_SETUP_FAILURE);
|
||||
}
|
||||
|
||||
result = getrlimit(RLIMIT_NOFILE, &file_limits);
|
||||
if (0 > result)
|
||||
{
|
||||
DPRINTFE("Failed to get file limits for script %s, error=%s.",
|
||||
script_exec, strerror(errno));
|
||||
exit(GUEST_SCRIPT_SETUP_FAILURE);
|
||||
}
|
||||
|
||||
unsigned int fd_i;
|
||||
for (fd_i=0; fd_i < file_limits.rlim_cur; ++fd_i)
|
||||
if (fd_i != fd[1])
|
||||
close(fd_i);
|
||||
|
||||
result = dup2(fd[1], 1); // make stdout into writable end of pipe
|
||||
if (0 > result)
|
||||
{
|
||||
DPRINTFE("Failed to make stdout into writable end of pipe for "
|
||||
"script %s, error=%s.", script_exec, strerror(errno));
|
||||
exit(GUEST_SCRIPT_SETUP_FAILURE);
|
||||
}
|
||||
|
||||
result = execv(script_exec, (char**) script_argv);
|
||||
if (0 > result)
|
||||
DPRINTFE("Failed to exec command for script %s, error=%s.",
|
||||
script_exec, strerror(errno));
|
||||
|
||||
exit(GUEST_SCRIPT_SETUP_FAILURE);
|
||||
|
||||
} else {
|
||||
// Parent process.
|
||||
close(fd[1]); // close write end of pipe
|
||||
entry->pid = (int) pid;
|
||||
entry->fd = fd[0];
|
||||
entry->inuse = true;
|
||||
|
||||
DPRINTFD("Child process %i created for script %s, script_id=%i.",
|
||||
entry->pid, script_name, entry->script_id);
|
||||
|
||||
error = guest_child_death_register(pid, guest_script_callback);
|
||||
if (GUEST_OKAY != error)
|
||||
{
|
||||
DPRINTFE("Failed to register for child death %i, error=%s.",
|
||||
entry->pid, guest_error_str(error));
|
||||
guest_script_abort(entry->script_id);
|
||||
return error;
|
||||
}
|
||||
|
||||
memset(&callbacks, 0, sizeof(callbacks));
|
||||
callbacks.read_callback = guest_script_dispatch;
|
||||
|
||||
error = guest_selobj_register(entry->fd, &callbacks);
|
||||
if (GUEST_OKAY != error)
|
||||
{
|
||||
DPRINTFE("Failed to register selection object %i, error=%s.",
|
||||
entry->fd, guest_error_str(error));
|
||||
guest_script_abort(entry->script_id);
|
||||
return error;
|
||||
}
|
||||
|
||||
*script_id = entry->script_id;
|
||||
}
|
||||
|
||||
return GUEST_OKAY;
|
||||
}
|
||||
// ****************************************************************************
|
||||
|
||||
// ****************************************************************************
|
||||
// Guest Script - Initialize
|
||||
// =========================
|
||||
GuestErrorT guest_script_initialize( void )
|
||||
{
|
||||
GuestScriptDataT* entry;
|
||||
|
||||
memset(_scripts, 0, sizeof(_scripts));
|
||||
|
||||
unsigned int script_i;
|
||||
for (script_i=0; GUEST_CHILD_PROCESS_MAX > script_i; ++script_i)
|
||||
{
|
||||
entry = &(_scripts[script_i]);
|
||||
|
||||
entry->pid = -1;
|
||||
entry->fd = -1;
|
||||
entry->script_id = GUEST_SCRIPT_ID_INVALID;
|
||||
}
|
||||
|
||||
return GUEST_OKAY;
|
||||
}
|
||||
// ****************************************************************************
|
||||
|
||||
// ****************************************************************************
|
||||
// Guest Script - Finalize
|
||||
// =======================
|
||||
GuestErrorT guest_script_finalize( void )
|
||||
{
|
||||
GuestScriptDataT* entry;
|
||||
|
||||
unsigned int script_i;
|
||||
for (script_i=0; GUEST_CHILD_PROCESS_MAX > script_i; ++script_i)
|
||||
{
|
||||
entry = &(_scripts[script_i]);
|
||||
if (entry->inuse)
|
||||
guest_script_abort(entry->script_id);
|
||||
}
|
||||
|
||||
memset(_scripts, 0, sizeof(_scripts));
|
||||
return GUEST_OKAY;
|
||||
}
|
||||
// ****************************************************************************
|
||||
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2016, Wind River Systems, Inc.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1) Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2) Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* 3) Neither the name of Wind River Systems nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software without specific
|
||||
* prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#ifndef __GUEST_SCRIPT_H__
|
||||
#define __GUEST_SCRIPT_H__
|
||||
|
||||
#include "guest_types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define GUEST_SCRIPT_ID_INVALID -1
|
||||
|
||||
typedef int GuestScriptIdT;
|
||||
|
||||
typedef void (*GuestScriptCallbackT)
|
||||
(GuestScriptIdT script_id,int exit_code, char* log_msg);
|
||||
|
||||
// ****************************************************************************
|
||||
// Guest Script - Abort
|
||||
// ====================
|
||||
extern void guest_script_abort( GuestScriptIdT script_id );
|
||||
// ****************************************************************************
|
||||
|
||||
// ****************************************************************************
|
||||
// Guest Script - Invoke
|
||||
// =====================
|
||||
extern GuestErrorT guest_script_invoke(
|
||||
char script[], char* script_argv[], GuestScriptCallbackT callback,
|
||||
GuestScriptIdT* script_id );
|
||||
// ****************************************************************************
|
||||
|
||||
// ****************************************************************************
|
||||
// Guest Script - Initialize
|
||||
// =========================
|
||||
extern GuestErrorT guest_script_initialize( void );
|
||||
// ****************************************************************************
|
||||
|
||||
// ****************************************************************************
|
||||
// Guest Script - Finalize
|
||||
// =======================
|
||||
extern GuestErrorT guest_script_finalize( void );
|
||||
// ****************************************************************************
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __GUEST_SCRIPT_H__ */
|
||||
@@ -0,0 +1,254 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2016, Wind River Systems, Inc.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1) Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2) Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation and/or
|
||||
* other materials provided with the distribution.
|
||||
*
|
||||
* 3) Neither the name of Wind River Systems nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software without specific
|
||||
* prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#include "guest_selobj.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <poll.h>
|
||||
|
||||
#include "guest_limits.h"
|
||||
#include "guest_types.h"
|
||||
#include "guest_debug.h"
|
||||
|
||||
typedef struct {
|
||||
bool inuse;
|
||||
int selobj;
|
||||
GuestSelObjCallbacksT callbacks;
|
||||
} GuestSelObjEntryT;
|
||||
|
||||
typedef GuestSelObjEntryT GuestSelObjTableT[GUEST_SELECT_OBJS_MAX];
|
||||
|
||||
static int _num_poll_fds = 0;
|
||||
static struct pollfd _poll_fds[GUEST_SELECT_OBJS_MAX];
|
||||
static GuestSelObjTableT _select_objs;
|
||||
|
||||
// ****************************************************************************
|
||||
// Guest Selection Object - Find Selection Object
|
||||
// ==============================================
|
||||
static GuestSelObjEntryT* guest_selobj_find( int selobj )
|
||||
{
|
||||
GuestSelObjEntryT* entry;
|
||||
|
||||
unsigned int entry_i;
|
||||
for (entry_i=0; GUEST_SELECT_OBJS_MAX > entry_i; ++entry_i)
|
||||
{
|
||||
entry = &(_select_objs[entry_i]);
|
||||
if (entry->inuse)
|
||||
if (selobj == entry->selobj)
|
||||
return entry;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
// ****************************************************************************
|
||||
|
||||
// ****************************************************************************
|
||||
// Guest Selection Object - Register
|
||||
// =================================
|
||||
GuestErrorT guest_selobj_register (
|
||||
int selobj, GuestSelObjCallbacksT* callbacks )
|
||||
{
|
||||
GuestSelObjEntryT* entry;
|
||||
|
||||
entry = guest_selobj_find(selobj);
|
||||
if (NULL == entry)
|
||||
{
|
||||
unsigned int entry_i;
|
||||
for (entry_i=0; GUEST_SELECT_OBJS_MAX > entry_i; ++entry_i)
|
||||
{
|
||||
entry = &(_select_objs[entry_i]);
|
||||
if (!entry->inuse )
|
||||
{
|
||||
entry->inuse = true;
|
||||
entry->selobj = selobj;
|
||||
memcpy(&(entry->callbacks), callbacks,
|
||||
sizeof(GuestSelObjCallbacksT));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Rebuild polling file descriptors.
|
||||
_num_poll_fds =0;
|
||||
|
||||
for (entry_i=0; GUEST_SELECT_OBJS_MAX > entry_i; ++entry_i)
|
||||
{
|
||||
entry = &(_select_objs[entry_i]);
|
||||
if (entry->inuse)
|
||||
{
|
||||
memset(&_poll_fds[_num_poll_fds], 0, sizeof(struct pollfd));
|
||||
|
||||
_poll_fds[_num_poll_fds].fd = entry->selobj;
|
||||
|
||||
if (NULL != entry->callbacks.read_callback)
|
||||
_poll_fds[_num_poll_fds].events |= POLLIN;
|
||||
|
||||
if (NULL != entry->callbacks.write_callback)
|
||||
_poll_fds[_num_poll_fds].events |= POLLOUT;
|
||||
|
||||
if (NULL != entry->callbacks.hangup_callback)
|
||||
_poll_fds[_num_poll_fds].events |= POLLHUP;
|
||||
|
||||
++_num_poll_fds;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
memcpy(&(entry->callbacks), callbacks, sizeof(GuestSelObjCallbacksT));
|
||||
}
|
||||
|
||||
return GUEST_OKAY;
|
||||
}
|
||||
// ****************************************************************************
|
||||
|
||||
// ****************************************************************************
|
||||
// Guest Selection Object - Deregister
|
||||
// ===================================
|
||||
GuestErrorT guest_selobj_deregister( int selobj )
|
||||
{
|
||||
GuestSelObjEntryT* entry;
|
||||
|
||||
entry = guest_selobj_find(selobj);
|
||||
if (NULL != entry)
|
||||
memset(entry, 0, sizeof(GuestSelObjEntryT));
|
||||
|
||||
// Rebuild polling file descriptors.
|
||||
_num_poll_fds =0;
|
||||
|
||||
unsigned int entry_i;
|
||||
for (entry_i=0; GUEST_SELECT_OBJS_MAX > entry_i; ++entry_i)
|
||||
{
|
||||
entry = &(_select_objs[entry_i]);
|
||||
if (entry->inuse)
|
||||
{
|
||||
memset(&_poll_fds[_num_poll_fds], 0, sizeof(struct pollfd));
|
||||
|
||||
_poll_fds[_num_poll_fds].fd = entry->selobj;
|
||||
|
||||
if (NULL != entry->callbacks.read_callback)
|
||||
_poll_fds[_num_poll_fds].events |= POLLIN;
|
||||
|
||||
if (NULL != entry->callbacks.write_callback)
|
||||
_poll_fds[_num_poll_fds].events |= POLLOUT;
|
||||
|
||||
if (NULL != entry->callbacks.hangup_callback)
|
||||
_poll_fds[_num_poll_fds].events |= POLLHUP;
|
||||
|
||||
++_num_poll_fds;
|
||||
}
|
||||
}
|
||||
|
||||
return GUEST_OKAY;
|
||||
}
|
||||
// ****************************************************************************
|
||||
|
||||
// ****************************************************************************
|
||||
// Guest Selection Object - Dispatch
|
||||
// =================================
|
||||
GuestErrorT guest_selobj_dispatch( unsigned int timeout_in_ms )
|
||||
{
|
||||
struct pollfd* poll_entry;
|
||||
GuestSelObjEntryT* entry;
|
||||
int result;
|
||||
|
||||
result = poll(_poll_fds, _num_poll_fds, timeout_in_ms);
|
||||
if (0 > result)
|
||||
{
|
||||
if (errno == EINTR)
|
||||
{
|
||||
DPRINTFD("Interrupted by a signal.");
|
||||
return GUEST_OKAY;
|
||||
} else {
|
||||
DPRINTFE("Select failed, error=%s.", strerror(errno));
|
||||
return GUEST_FAILED;
|
||||
}
|
||||
} else if (0 == result) {
|
||||
DPRINTFV("Nothing selected.");
|
||||
return GUEST_OKAY;
|
||||
}
|
||||
|
||||
unsigned int entry_i;
|
||||
for (entry_i=0; _num_poll_fds > entry_i; ++entry_i)
|
||||
{
|
||||
poll_entry = &(_poll_fds[entry_i]);
|
||||
|
||||
entry = guest_selobj_find(poll_entry->fd);
|
||||
if (NULL != entry)
|
||||
{
|
||||
if (0 != (poll_entry->revents & POLLIN))
|
||||
if (NULL != entry->callbacks.read_callback)
|
||||
{
|
||||
DPRINTFD("Read on selection object %i", poll_entry->fd);
|
||||
entry->callbacks.read_callback(entry->selobj);
|
||||
}
|
||||
|
||||
if (0 != (poll_entry->revents & POLLOUT))
|
||||
if (NULL != entry->callbacks.write_callback)
|
||||
{
|
||||
DPRINTFD("Write on selection object %i", poll_entry->fd);
|
||||
entry->callbacks.write_callback(entry->selobj);
|
||||
}
|
||||
|
||||
if (0 != (poll_entry->revents & POLLHUP))
|
||||
if (NULL != entry->callbacks.hangup_callback)
|
||||
{
|
||||
DPRINTFD("Hangup on selection object %i", poll_entry->fd);
|
||||
entry->callbacks.hangup_callback(entry->selobj);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return GUEST_OKAY;
|
||||
}
|
||||
// ****************************************************************************
|
||||
|
||||
// ****************************************************************************
|
||||
// Guest Selection Object - Initialize
|
||||
// ===================================
|
||||
GuestErrorT guest_selobj_initialize( void )
|
||||
{
|
||||
_num_poll_fds = 0;
|
||||
memset(_poll_fds, 0, sizeof(_poll_fds));
|
||||
memset(_select_objs, 0, sizeof(GuestSelObjTableT));
|
||||
return GUEST_OKAY;
|
||||
}
|
||||
// ****************************************************************************
|
||||
|
||||
// ****************************************************************************
|
||||
// Guest Selection Object - Finalize
|
||||
// =================================
|
||||
GuestErrorT guest_selobj_finalize( void )
|
||||
{
|
||||
_num_poll_fds = 0;
|
||||
memset(_poll_fds, 0, sizeof(_poll_fds));
|
||||
memset(_select_objs, 0, sizeof(GuestSelObjTableT));
|
||||
return GUEST_OKAY;
|
||||
}
|
||||
// ****************************************************************************
|
||||
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2016, Wind River Systems, Inc.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||