Add support for container/contained samples. --- samples/amf/Makefile.am | 2 +- samples/amf/container/AppConfig-contained-2N.xml | 327 +++++++++ samples/amf/container/AppConfig-container.xml | 331 ++++++++++ samples/amf/container/Makefile.am | 45 ++ samples/amf/container/README | 36 + samples/amf/container/amf_container_demo.c | 803 +++++++++++++++++++++++ samples/amf/container/amf_container_script | 101 +++ samples/configure.ac | 1 + tools/cluster_sim_uml/build_uml | 45 ++ 9 files changed, 1690 insertions(+), 1 deletion(-) create mode 100644 samples/amf/container/AppConfig-contained-2N.xml create mode 100644 samples/amf/container/AppConfig-container.xml create mode 100644 samples/amf/container/Makefile.am create mode 100644 samples/amf/container/README create mode 100644 samples/amf/container/amf_container_demo.c create mode 100755 samples/amf/container/amf_container_script
diff --git a/samples/amf/Makefile.am b/samples/amf/Makefile.am index 447dedd20..7ebf9c3a5 100644 --- a/samples/amf/Makefile.am +++ b/samples/amf/Makefile.am @@ -19,5 +19,5 @@ include $(top_srcdir)/Makefile.common MAINTAINERCLEANFILES = Makefile.in -SUBDIRS = sa_aware non_sa_aware wrapper proxy api_demo +SUBDIRS = sa_aware non_sa_aware wrapper proxy api_demo container diff --git a/samples/amf/container/AppConfig-contained-2N.xml b/samples/amf/container/AppConfig-contained-2N.xml new file mode 100644 index 000000000..b8f7c572d --- /dev/null +++ b/samples/amf/container/AppConfig-contained-2N.xml @@ -0,0 +1,327 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + * -*- OpenSAF -*- + * + * (C) Copyright 2009 The OpenSAF Foundation + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. This file and program are licensed + * under the GNU Lesser General Public License Version 2.1, February 1999. + * The complete license can be accessed from the following location: + * http://opensource.org/licenses/lgpl-license.php + * See the Copying file included with the OpenSAF distribution for full + * licensing terms. + * + * Author(s): Ericsson + * + +- Admin state of SUs is LOCKED-INSTANTIATION which makes it possible to load +this file using "immcfg -f" + +- With only node in the cluster this object needs to be removed: +"safInstalledSwBundle=safSmfBundle=Contained_2N,safAmfNode=SC-2,safAmfCluster=myAmfCluster" +from the file before loaded. + +--> + +<imm:IMM-contents xmlns:imm="http://www.saforum.org/IMMSchema" xsi:noNamespaceSchemaLocation="SAI-AIS-IMM-XSD-A.01.01.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + <object class="SaAmfAppBaseType"> + <dn>safAppType=Contained1</dn> + </object> + <object class="SaAmfSGBaseType"> + <dn>safSgType=Contained1</dn> + </object> + <object class="SaAmfSUBaseType"> + <dn>safSuType=Contained1</dn> + </object> + <object class="SaAmfCompBaseType"> + <dn>safCompType=Contained1</dn> + </object> + <object class="SaAmfSvcBaseType"> + <dn>safSvcType=Contained1</dn> + </object> + <object class="SaAmfCSBaseType"> + <dn>safCSType=Contained1</dn> + </object> + <object class="SaAmfSvcType"> + <dn>safVersion=1,safSvcType=Contained1</dn> + </object> + <object class="SaAmfAppType"> + <dn>safVersion=1,safAppType=Contained1</dn> + <attr> + <name>saAmfApptSGTypes</name> + <value>safVersion=1,safSgType=Contained1</value> + </attr> + </object> + <object class="SaAmfSGType"> + <dn>safVersion=1,safSgType=Contained1</dn> + <attr> + <name>saAmfSgtRedundancyModel</name> + <value>1</value> + </attr> + <attr> + <name>saAmfSgtValidSuTypes</name> + <value>safVersion=1,safSuType=Contained1</value> + </attr> + <attr> + <name>saAmfSgtDefAutoAdjustProb</name> + <value>10000000000</value> + </attr> + <attr> + <name>saAmfSgtDefCompRestartProb</name> + <value>4000000000</value> + </attr> + <attr> + <name>saAmfSgtDefCompRestartMax</name> + <value>10</value> + </attr> + <attr> + <name>saAmfSgtDefSuRestartProb</name> + <value>4000000000</value> + </attr> + <attr> + <name>saAmfSgtDefSuRestartMax</name> + <value>10</value> + </attr> + </object> + <object class="SaAmfSUType"> + <dn>safVersion=1,safSuType=Contained1</dn> + <attr> + <name>saAmfSutIsExternal</name> + <value>0</value> + </attr> + <attr> + <name>saAmfSutDefSUFailover</name> + <value>1</value> + </attr> + <attr> + <name>saAmfSutProvidesSvcTypes</name> + <value>safVersion=1,safSvcType=Contained1</value> + </attr> + </object> + <object class="SaAmfCompType"> + <dn>safVersion=1,safCompType=Contained1</dn> + <attr> + <name>saAmfCtCompCategory</name> + <value>32</value> + </attr> + <attr> + <name>saAmfCtSwBundle</name> + <value>safSmfBundle=Contained_2N</value> + </attr> + <attr> + <name>saAmfCtDefClcCliTimeout</name> + <value>90000000000</value> + </attr> + <attr> + <name>saAmfCtDefCallbackTimeout</name> + <value>90000000000</value> + </attr> + <attr> + <name>saAmfCtRelPathInstantiateCmd</name> + <value>amf_container_script</value> + </attr> + <attr> + <name>saAmfCtDefInstantiateCmdArgv</name> + <value>instantiate</value> + </attr> + <attr> + <name>saAmfCtRelPathCleanupCmd</name> + <value>amf_container_script</value> + </attr> + <attr> + <name>saAmfCtDefCleanupCmdArgv</name> + <value>cleanup_contained</value> + </attr> + <attr> + <name>saAmfCtDefQuiescingCompleteTimeout</name> + <value>90000000000</value> + </attr> + <attr> + <name>saAmfCtDefRecoveryOnError</name> + <value>2</value> + </attr> + <attr> + <name>saAmfCtDefDisableRestart</name> + <value>0</value> + </attr> + <attr> + <name>saAmfCtDefCmdEnv</name> + <value>AMF_DEMO_VAR1=CT_VALUE1</value> + <value>AMF_DEMO_VAR2=CT_VALUE2</value> + </attr> + </object> + <object class="SaAmfCSType"> + <dn>safVersion=1,safCSType=Contained1</dn> + </object> + <object class="SaAmfSutCompType"> + <dn>safMemberCompType=safVersion=1\,safCompType=Contained1,safVersion=1,safSuType=Contained1</dn> + </object> + <object class="SaAmfSvcTypeCSTypes"> + <dn>safMemberCSType=safVersion=1\,safCSType=Contained1,safVersion=1,safSvcType=Contained1</dn> + </object> + <object class="SaAmfCtCsType"> + <dn>safSupportedCsType=safVersion=1\,safCSType=Contained1,safVersion=1,safCompType=Contained1</dn> + <attr> + <name>saAmfCtCompCapability</name> + <value>1</value> + </attr> + </object> + <object class="SaAmfHealthcheckType"> + <dn>safHealthcheckKey=Contained_2N_1,safVersion=1,safCompType=Contained1</dn> + <attr> + <name>saAmfHctDefPeriod</name> + <value>10000000000</value> + </attr> + <attr> + <name>saAmfHctDefMaxDuration</name> + <value>6000000000</value> + </attr> + </object> + + <object class="SaAmfApplication"> + <dn>safApp=Contained_2N</dn> + <attr> + <name>saAmfAppType</name> + <value>safVersion=1,safAppType=Contained1</value> + </attr> + </object> + <object class="SaAmfSG"> + <dn>safSg=Contained_2N,safApp=Contained_2N</dn> + <attr> + <name>saAmfSGType</name> + <value>safVersion=1,safSgType=Contained1</value> + </attr> + <attr> + <name>saAmfSGSuHostNodeGroup</name> + <value>safAmfNodeGroup=SCs,safAmfCluster=myAmfCluster</value> + </attr> + <attr> + <name>saAmfSGAutoRepair</name> + <value>0</value> + </attr> + <attr> + <name>saAmfSGAutoAdjust</name> + <value>0</value> + </attr> + <attr> + <name>saAmfSGNumPrefInserviceSUs</name> + <value>10</value> + </attr> + <attr> + <name>saAmfSGNumPrefAssignedSUs</name> + <value>10</value> + </attr> + </object> + <object class="SaAmfSI"> + <dn>safSi=Contained_2N_1,safApp=Contained_2N</dn> + <attr> + <name>saAmfSvcType</name> + <value>safVersion=1,safSvcType=Contained1</value> + </attr> + <attr> + <name>saAmfSIProtectedbySG</name> + <value>safSg=Contained_2N,safApp=Contained_2N</value> + </attr> + </object> + <object class="SaAmfCSI"> + <dn>safCsi=Contained_2N_1,safSi=Contained_2N_1,safApp=Contained_2N</dn> + <attr> + <name>saAmfCSType</name> + <value>safVersion=1,safCSType=Contained1</value> + </attr> + </object> + <object class="SaSmfSwBundle"> + <dn>safSmfBundle=Contained_2N</dn> + </object> + <object class="SaAmfNodeSwBundle"> + <dn>safInstalledSwBundle=safSmfBundle=Contained_2N,safAmfNode=SC-1,safAmfCluster=myAmfCluster</dn> + <attr> + <name>saAmfNodeSwBundlePathPrefix</name> + <value>/opt/amf_demo</value> + </attr> + </object> + <object class="SaAmfSU"> + <dn>safSu=SU1,safSg=Contained_2N,safApp=Contained_2N</dn> + <attr> + <name>saAmfSUType</name> + <value>safVersion=1,safSuType=Contained1</value> + </attr> + <attr> + <name>saAmfSURank</name> + <value>1</value> + </attr> + <attr> + <name>saAmfSUAdminState</name> + <value>3</value> + </attr> + </object> + <object class="SaAmfComp"> + <dn>safComp=Contained_1,safSu=SU1,safSg=Contained_2N,safApp=Contained_2N</dn> + <attr> + <name>saAmfCompType</name> + <value>safVersion=1,safCompType=Contained1</value> + </attr> + <attr> + <name>saAmfCompContainerCsi</name> + <value>safCsi=Container1,safSi=Container,safApp=Container</value> + </attr> + <attr> + <name>saAmfCompCmdEnv</name> + <value>AMF_DEMO_VAR2=COMP1_OVERLOAD_VALUE2</value> + </attr> + </object> + <object class="SaAmfCompCsType"> + <dn>safSupportedCsType=safVersion=1\,safCSType=Contained1,safComp=Contained_1,safSu=SU1,safSg=Contained_2N,safApp=Contained_2N</dn> + </object> + <object class="SaAmfNodeSwBundle"> + <dn>safInstalledSwBundle=safSmfBundle=Contained_2N,safAmfNode=SC-2,safAmfCluster=myAmfCluster</dn> + <attr> + <name>saAmfNodeSwBundlePathPrefix</name> + <value>/opt/amf_demo</value> + </attr> + </object> + <object class="SaAmfSU"> + <dn>safSu=SU2,safSg=Contained_2N,safApp=Contained_2N</dn> + <attr> + + <name>saAmfSUType</name> + <value>safVersion=1,safSuType=Contained1</value> + </attr> + <attr> + <name>saAmfSURank</name> + <value>2</value> + </attr> + <attr> + <name>saAmfSUAdminState</name> + <value>3</value> + </attr> + </object> + <object class="SaAmfComp"> + <dn>safComp=Contained_1,safSu=SU2,safSg=Contained_2N,safApp=Contained_2N</dn> + <attr> + <name>saAmfCompType</name> + <value>safVersion=1,safCompType=Contained1</value> + </attr> + <attr> + <name>saAmfCompContainerCsi</name> + <value>safCsi=Container1,safSi=Container,safApp=Container</value> + </attr> + <attr> + <name>saAmfCompCmdEnv</name> + <value>AMF_DEMO_VAR2=COMP2_OVERLOAD_VALUE2</value> + </attr> + </object> + <object class="SaAmfCompCsType"> + <dn>safSupportedCsType=safVersion=1\,safCSType=Contained1,safComp=Contained_1,safSu=SU2,safSg=Contained_2N,safApp=Contained_2N</dn> + </object> + <object class="SaAmfCSIAttribute"> + <dn>safCsiAttr=Contained_2N_1,safCsi=Contained_2N_1,safSi=Contained_2N_1,safApp=Contained_2N</dn> + <attr> + <name>saAmfCSIAttriValue</name> + <value>AAAA</value> + <value>BBBB</value> + </attr> + </object> +</imm:IMM-contents> diff --git a/samples/amf/container/AppConfig-container.xml b/samples/amf/container/AppConfig-container.xml new file mode 100644 index 000000000..bdcdd7e2c --- /dev/null +++ b/samples/amf/container/AppConfig-container.xml @@ -0,0 +1,331 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + * -*- OpenSAF -*- + * + * (C) Copyright 2009 The OpenSAF Foundation + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. This file and program are licensed + * under the GNU Lesser General Public License Version 2.1, February 1999. + * The complete license can be accessed from the following location: + * http://opensource.org/licenses/lgpl-license.php + * See the Copying file included with the OpenSAF distribution for full + * licensing terms. + * + * Author(s): Ericsson + * + +- Admin state of SUs is LOCKED-INSTANTIATION which makes it possible to load +this file using "immcfg -f" + +- With only node in the cluster this object needs to be removed: +"safInstalledSwBundle=safSmfBundle=Container,safAmfNode=SC-2,safAmfCluster=myAmfCluster" +from the file before loaded. + +--> + +<imm:IMM-contents xmlns:imm="http://www.saforum.org/IMMSchema" xsi:noNamespaceSchemaLocation="SAI-AIS-IMM-XSD-A.01.01.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + <object class="SaAmfAppBaseType"> + <dn>safAppType=Container</dn> + </object> + <object class="SaAmfSGBaseType"> + <dn>safSgType=Container</dn> + </object> + <object class="SaAmfSUBaseType"> + <dn>safSuType=Container</dn> + </object> + <object class="SaAmfCompBaseType"> + <dn>safCompType=Container</dn> + </object> + <object class="SaAmfSvcBaseType"> + <dn>safSvcType=Container</dn> + </object> + <object class="SaAmfCSBaseType"> + <dn>safCSType=Container</dn> + </object> + <object class="SaAmfSvcType"> + <dn>safVersion=1,safSvcType=Container</dn> + </object> + <object class="SaAmfAppType"> + <dn>safVersion=1,safAppType=Container</dn> + <attr> + <name>saAmfApptSGTypes</name> + <value>safVersion=1,safSgType=Container</value> + </attr> + </object> + <object class="SaAmfSGType"> + <dn>safVersion=1,safSgType=Container</dn> + <attr> + <name>saAmfSgtRedundancyModel</name> + <value>4</value> + </attr> + <attr> + <name>saAmfSgtValidSuTypes</name> + <value>safVersion=1,safSuType=Container</value> + </attr> + <attr> + <name>saAmfSgtDefAutoAdjustProb</name> + <value>10000000000</value> + </attr> + <attr> + <name>saAmfSgtDefCompRestartProb</name> + <value>4000000000</value> + </attr> + <attr> + <name>saAmfSgtDefCompRestartMax</name> + <value>10</value> + </attr> + <attr> + <name>saAmfSgtDefSuRestartProb</name> + <value>4000000000</value> + </attr> + <attr> + <name>saAmfSgtDefSuRestartMax</name> + <value>10</value> + </attr> + </object> + <object class="SaAmfSUType"> + <dn>safVersion=1,safSuType=Container</dn> + <attr> + <name>saAmfSutIsExternal</name> + <value>0</value> + </attr> + <attr> + <name>saAmfSutDefSUFailover</name> + <value>1</value> + </attr> + <attr> + <name>saAmfSutProvidesSvcTypes</name> + <value>safVersion=1,safSvcType=Container</value> + </attr> + </object> + <object class="SaAmfCompType"> + <dn>safVersion=1,safCompType=Container</dn> + <attr> + <name>saAmfCtCompCategory</name> + <value>16</value> + </attr> + <attr> + <name>saAmfCtSwBundle</name> + <value>safSmfBundle=Container</value> + </attr> + <attr> + <name>saAmfCtDefClcCliTimeout</name> + <value>10000000000</value> + </attr> + <attr> + <name>saAmfCtDefCallbackTimeout</name> + <value>10000000000</value> + </attr> + <attr> + <name>saAmfCtRelPathInstantiateCmd</name> + <value>amf_container_script</value> + </attr> + <attr> + <name>saAmfCtDefInstantiateCmdArgv</name> + <value>instantiate</value> + </attr> + <attr> + <name>saAmfCtRelPathCleanupCmd</name> + <value>amf_container_script</value> + </attr> + <attr> + <name>saAmfCtDefCleanupCmdArgv</name> + <value>cleanup</value> + </attr> + <attr> + <name>saAmfCtDefQuiescingCompleteTimeout</name> + <value>10000000000</value> + </attr> + <attr> + <name>saAmfCtDefRecoveryOnError</name> + <value>2</value> + </attr> + <attr> + <name>saAmfCtDefDisableRestart</name> + <value>0</value> + </attr> + <attr> + <name>saAmfCtDefCmdEnv</name> + <value>AMF_DEMO_VAR1=CT_VALUE1</value> + <value>AMF_DEMO_VAR2=CT_VALUE2</value> + </attr> + </object> + <object class="SaAmfCSType"> + <dn>safVersion=1,safCSType=Container</dn> + </object> + <object class="SaAmfSutCompType"> + <dn>safMemberCompType=safVersion=1\,safCompType=Container,safVersion=1,safSuType=Container</dn> + </object> + <object class="SaAmfSvcTypeCSTypes"> + <dn>safMemberCSType=safVersion=1\,safCSType=Container,safVersion=1,safSvcType=Container</dn> + </object> + <object class="SaAmfCtCsType"> + <dn>safSupportedCsType=safVersion=1\,safCSType=Container,safVersion=1,safCompType=Container</dn> + <attr> + <name>saAmfCtCompCapability</name> + <value>1</value> + </attr> + </object> + <object class="SaAmfHealthcheckType"> + <dn>safHealthcheckKey=Container1,safVersion=1,safCompType=Container</dn> + <attr> + <name>saAmfHctDefPeriod</name> + <value>10000000000</value> + </attr> + <attr> + <name>saAmfHctDefMaxDuration</name> + <value>6000000000</value> + </attr> + </object> + + <object class="SaAmfApplication"> + <dn>safApp=Container</dn> + <attr> + <name>saAmfAppType</name> + <value>safVersion=1,safAppType=Container</value> + </attr> + </object> + <object class="SaAmfSG"> + <dn>safSg=Container,safApp=Container</dn> + <attr> + <name>saAmfSGType</name> + <value>safVersion=1,safSgType=Container</value> + </attr> + <attr> + <name>saAmfSGSuHostNodeGroup</name> + <value>safAmfNodeGroup=SCs,safAmfCluster=myAmfCluster</value> + </attr> + <attr> + <name>saAmfSGAutoRepair</name> + <value>0</value> + </attr> + <attr> + <name>saAmfSGAutoAdjust</name> + <value>0</value> + </attr> + <attr> + <name>saAmfSGNumPrefInserviceSUs</name> + <value>10</value> + </attr> + <attr> + <name>saAmfSGNumPrefAssignedSUs</name> + <value>10</value> + </attr> + </object> + <object class="SaAmfSI"> + <dn>safSi=Container,safApp=Container</dn> + <attr> + <name>saAmfSvcType</name> + <value>safVersion=1,safSvcType=Container</value> + </attr> + <attr> + <name>saAmfSIProtectedbySG</name> + <value>safSg=Container,safApp=Container</value> + </attr> + <attr> + <name>saAmfSIPrefActiveAssignments</name> + <value>2</value> + </attr> + </object> + <object class="SaAmfCSI"> + <dn>safCsi=Container1,safSi=Container,safApp=Container</dn> + <attr> + <name>saAmfCSType</name> + <value>safVersion=1,safCSType=Container</value> + </attr> + </object> + <object class="SaSmfSwBundle"> + <dn>safSmfBundle=Container</dn> + </object> + <object class="SaAmfNodeSwBundle"> + <dn>safInstalledSwBundle=safSmfBundle=Container,safAmfNode=SC-1,safAmfCluster=myAmfCluster</dn> + <attr> + <name>saAmfNodeSwBundlePathPrefix</name> + <value>/opt/amf_demo</value> + </attr> + </object> + <object class="SaAmfSU"> + <dn>safSu=SU1,safSg=Container,safApp=Container</dn> + <attr> + <name>saAmfSUType</name> + <value>safVersion=1,safSuType=Container</value> + </attr> + <attr> + <name>saAmfSURank</name> + <value>1</value> + </attr> + <attr> + <name>saAmfSUAdminState</name> + <value>3</value> + </attr> + <attr> + <name>saAmfSUHostNodeOrNodeGroup</name> + <value>safAmfNode=SC-1,safAmfCluster=myAmfCluster</value> + </attr> + </object> + <object class="SaAmfComp"> + <dn>safComp=Container,safSu=SU1,safSg=Container,safApp=Container</dn> + <attr> + <name>saAmfCompType</name> + <value>safVersion=1,safCompType=Container</value> + </attr> + <attr> + <name>saAmfCompCmdEnv</name> + <value>AMF_CONTAINER1=safComp=Contained_1,safSu=SU1,safSg=Contained_2N,safApp=Contained_2N</value> + </attr> + </object> + <object class="SaAmfCompCsType"> + <dn>safSupportedCsType=safVersion=1\,safCSType=Container,safComp=Container,safSu=SU1,safSg=Container,safApp=Container</dn> + </object> + <object class="SaAmfNodeSwBundle"> + <dn>safInstalledSwBundle=safSmfBundle=Container,safAmfNode=SC-2,safAmfCluster=myAmfCluster</dn> + <attr> + <name>saAmfNodeSwBundlePathPrefix</name> + <value>/opt/amf_demo</value> + </attr> + </object> + <object class="SaAmfSU"> + <dn>safSu=SU2,safSg=Container,safApp=Container</dn> + <attr> + + <name>saAmfSUType</name> + <value>safVersion=1,safSuType=Container</value> + </attr> + <attr> + <name>saAmfSURank</name> + <value>2</value> + </attr> + <attr> + <name>saAmfSUAdminState</name> + <value>3</value> + </attr> + <attr> + <name>saAmfSUHostNodeOrNodeGroup</name> + <value>safAmfNode=SC-2,safAmfCluster=myAmfCluster</value> + </attr> + </object> + <object class="SaAmfComp"> + <dn>safComp=Container,safSu=SU2,safSg=Container,safApp=Container</dn> + <attr> + <name>saAmfCompType</name> + <value>safVersion=1,safCompType=Container</value> + </attr> + <attr> + <name>saAmfCompCmdEnv</name> + <value>AMF_CONTAINER1=safComp=Contained_1,safSu=SU2,safSg=Contained_2N,safApp=Contained_2N</value> + </attr> + </object> + <object class="SaAmfCompCsType"> + <dn>safSupportedCsType=safVersion=1\,safCSType=Container,safComp=Container,safSu=SU2,safSg=Container,safApp=Container</dn> + </object> + <object class="SaAmfCSIAttribute"> + <dn>safCsiAttr=Contained1,safCsi=Container1,safSi=Container,safApp=Container</dn> + <attr> + <name>saAmfCSIAttriValue</name> + <value>AAAA</value> + <value>BBBB</value> + </attr> + </object> +</imm:IMM-contents> diff --git a/samples/amf/container/Makefile.am b/samples/amf/container/Makefile.am new file mode 100644 index 000000000..299a947c8 --- /dev/null +++ b/samples/amf/container/Makefile.am @@ -0,0 +1,45 @@ +# -*- OpenSAF -*- +# +# (C) Copyright 2010 The OpenSAF Foundation +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +# or FITNESS FOR A PARTICULAR PURPOSE. This file and program are licensed +# under the GNU Lesser General Public License Version 2.1, February 1999. +# The complete license can be accessed from the following location: +# http://opensource.org/licenses/lgpl-license.php +# See the Copying file included with the OpenSAF distribution for full +# licensing terms. +# +# Author(s): Wind River Systems +# + +include $(top_srcdir)/Makefile.common + +MAINTAINERCLEANFILES = Makefile.in + +EXTRA_DIST = \ + amf_container_demo_script \ + AppConfig-container.xml \ + AppConfig-contained-2N.xml \ + README + +bin_PROGRAMS = amf_container_demo + +amf_container_demo_CPPFLAGS = \ + -DSA_EXTENDED_NAME_SOURCE \ + $(AM_CPPFLAGS) + +amf_container_demo_SOURCES = \ + amf_container_demo.c + +amf_container_demo_LDADD = \ + @SAF_AIS_AMF_LIBS@ + +install-data-hook: + $(mkinstalldirs) $(DESTDIR)/opt/amf_demo + cp amf_container_demo $(DESTDIR)/opt/amf_demo + cp amf_container_script $(DESTDIR)/opt/amf_demo + +uninstall-hook: + rm -rf $(DESTDIR)/opt/amf_demo diff --git a/samples/amf/container/README b/samples/amf/container/README new file mode 100644 index 000000000..c76e32da5 --- /dev/null +++ b/samples/amf/container/README @@ -0,0 +1,36 @@ +This directory contains a sample implementation of an +SA-Aware AMF component. + +amf_demo.c contains the skeleton of an SA-Aware AMF component. All required +callbacks are implemented and responds OK when requested. To be used with +any of the configuration files mentioned below. This implementation can be +used as a starting point to see what happens when you do admin operations +such as lock, lock-instantiation etc on SU or any other level containing +the component. + +Logging output is done to the system log (normally /var/log/message). + +Appconfig-2N.xml: This file contains the AMF model for an application running +in a 2N redundancy model. The amf_demo is configured to run on the 2 controllers. + +Appconfig-nwayactive.xml: This file contains the AMF model for an application +running in an NWayActive redundancy model. The configuration contains 5 SUs +That will run on the "allnodes" AMF node group. + +Note that the SU admin state has the value UNLOCKED-INSTANTIATION(3). This +means that the SUs needs to be unlocked after the file has been loaded. + +Some steps to follow: + +1. Install amf_demo into /opt/amf_demo +2. Install amf_demo_script into /opt/amf_demo +3. Load configuration: immcfg -f AppConfig-2N.xml +4. Unlock instantiation: + amf-adm unlock-in safSu=SU1,safSg=AmfDemo,safApp=AmfDemo1 + amf-adm unlock-in safSu=SU2,safSg=AmfDemo,safApp=AmfDemo1 +5. Unlock: + amf-adm unlock safSu=SU1,safSg=AmfDemo,safApp=AmfDemo1 + amf-adm unlock safSu=SU2,safSg=AmfDemo,safApp=AmfDemo1 +6. Run below command for invocation of CSI Attribute Change Callback : + immcfg -a saAmfCSIAttriValue+=CCCC safCsiAttr=AmfDemo1,safCsi=AmfDemo,safSi=AmfDemo,safApp=AmfDemo1 + diff --git a/samples/amf/container/amf_container_demo.c b/samples/amf/container/amf_container_demo.c new file mode 100644 index 000000000..16e33dd4b --- /dev/null +++ b/samples/amf/container/amf_container_demo.c @@ -0,0 +1,803 @@ + +/* -*- OpenSAF -*- + * + * (C) Copyright 2009 The OpenSAF Foundation + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. This file and program are licensed + * under the GNU Lesser General Public License Version 2.1, February 1999. + * The complete license can be accessed from the following location: + * http://opensource.org/licenses/lgpl-license.php + * See the Copying file included with the OpenSAF distribution for full + * licensing terms. + * + * Author(s): Ericsson + */ + +/***************************************************************************** + + DESCRIPTION: + + This file contains a sample AMF component. It behaves nicely and responds OK + to every AMF request. + It can be used as a template for making a service SA-Aware. + + References are made to sequence diagrams in the AMF specification B.04 + +****************************************************************************** +*/ + +#include <stdio.h> +#include <string.h> +#include <errno.h> +#include <stdbool.h> +#include <stdlib.h> +#include <unistd.h> +#include <poll.h> +#include <syslog.h> +#include <libgen.h> +#include <signal.h> +#include <saAmf.h> +#include <saAis.h> +#include <malloc.h> +#include <ctype.h> + +#define MD5_LEN 32 +// extern void saAisNameLend(SaConstStringT value, SaNameT* name); +// extern SaConstStringT saAisNameBorrow(const SaNameT* name); +/* Some dummies in place of real service logic */ +int foo_activate(void) { return 0; } + +int foo_deactivate(void) { return 0; } + +int foo_healthcheck(void) { return 0; } + +/* AMF Handle */ +static SaAmfHandleT my_amf_hdl; +static SaAmfHandleT contained_amf_hdl; + +/* HealthCheck Key on which ddhealthcheck is started */ +//static SaAmfHealthcheckKeyT my_healthcheck_key = {"Container1", 10}; + +/* HA state of the application */ +static SaAmfHAStateT my_ha_state; +static SaAmfHAStateT contained_ha_state; + +/* Distinguised Name of the AMF component */ +static SaNameT my_comp_name; + +/* Logical HA State names for nicer logging */ +static const char *ha_state_name[] = { + "None", "Active", /* SA_AMF_HA_ACTIVE */ + "Standby", /* SA_AMF_HA_STANDBY */ + "Quiesced", /* SA_AMF_HA_QUIESCED */ + "Quiescing" /* SA_AMF_HA_QUIESCING */ +}; + +/** + * AMF invokes this callback to assign a new workload (ADD_ONE) or + * to change state of an already assigned workload (TARGET_ALL). + * The callback is used for the initial assignment, as a consequence + * of admin operations and fail/switch-over + * + * See example sequence diagrams in chapter 10. + * + * @param invocation + * @param comp_name + * @param ha_state + * @param csi_desc + */ +static void amf_csi_set_callback(SaInvocationT invocation, + const SaNameT *comp_name, + SaAmfHAStateT ha_state, + SaAmfCSIDescriptorT csi_desc) +{ + SaAisErrorT rc, error; + SaAmfCSIAttributeT *attr; + int i, status; + + syslog(LOG_INFO, "csi set callback for comp: %s", + saAisNameBorrow(comp_name)); + + if (csi_desc.csiFlags == SA_AMF_CSI_ADD_ONE) { + + syslog(LOG_INFO, "CSI Set - add '%s' HAState %s", + saAisNameBorrow(&csi_desc.csiName), + ha_state_name[ha_state]); + + /* For debug log the CSI attributes, they could + ** define the workload characteristics */ + for (i = 0; i < csi_desc.csiAttr.number; i++) { + attr = &csi_desc.csiAttr.attr[i]; + syslog(LOG_DEBUG, " name: %s, value: %s", + attr->attrName, attr->attrValue); + } + + } else if (csi_desc.csiFlags == SA_AMF_CSI_TARGET_ALL) { + syslog(LOG_INFO, "CSI Set - HAState %s for all assigned CSIs", + ha_state_name[ha_state]); + } else { + syslog(LOG_INFO, "CSI Set - HAState %s for '%s'", + ha_state_name[ha_state], + saAisNameBorrow(&csi_desc.csiName)); + } + + switch (ha_state) { + case SA_AMF_HA_ACTIVE: + status = foo_activate(); + break; + case SA_AMF_HA_STANDBY: + /* + * Not much to do in this simple example code + * For real one could open a checkpoint for reads + * Open a communication channel for listening + * etc. + */ + status = 0; + break; + case SA_AMF_HA_QUIESCED: + /* the effect of admin op lock on SU or node or ... */ + status = foo_deactivate(); + break; + case SA_AMF_HA_QUIESCING: + /* the effect of admin op lock on SU or node or ... */ + status = 0; + break; + default: + syslog(LOG_ERR, "unmanaged HA state %u", ha_state); + status = -1; + break; + } + + if (status == 0) + error = SA_AIS_OK; + else + error = SA_AIS_ERR_FAILED_OPERATION; + + rc = saAmfResponse_4(my_amf_hdl, invocation, 0, error); + if (rc != SA_AIS_OK) { + syslog(LOG_ERR, "saAmfResponse_4 FAILED - %u", rc); + exit(1); + } + + if (ha_state == SA_AMF_HA_QUIESCING) { + /* "gracefully quiescing CSI work assignment" */ + sleep(1); + rc = saAmfCSIQuiescingComplete(my_amf_hdl, invocation, + SA_AIS_OK); + if (rc != SA_AIS_OK) { + syslog(LOG_ERR, "saAmfCSIQuiescingComplete FAILED - %u", + rc); + exit(1); + } + if (csi_desc.csiFlags == SA_AMF_CSI_TARGET_ONE) { + rc = saAmfHAStateGet(my_amf_hdl, comp_name, + &csi_desc.csiName, &my_ha_state); + if (rc != SA_AIS_OK) { + syslog(LOG_ERR, "saAmfHAStateGet FAILED - %u", + rc); + exit(1); + } + } else if (csi_desc.csiFlags == SA_AMF_CSI_TARGET_ALL) { + // Application could iterate saAmfHAStateGet() for every + // csi which had been assigned to this component to + // ensure all csi(s) are QUIESCED + + // temporary set to QUIESCED + my_ha_state = SA_AMF_HA_QUIESCED; + } + + syslog(LOG_INFO, "My HA state is %s", + ha_state_name[my_ha_state]); + } +} + +static void contained_csi_set_callback(SaInvocationT invocation, + const SaNameT *comp_name, + SaAmfHAStateT ha_state, + SaAmfCSIDescriptorT csi_desc) +{ + SaAisErrorT rc, error; + SaAmfCSIAttributeT *attr; + int i, status; + + syslog(LOG_INFO, "csi set callback for comp: %s", + saAisNameBorrow(comp_name)); + + if (csi_desc.csiFlags == SA_AMF_CSI_ADD_ONE) { + + syslog(LOG_INFO, "CSI Set - add '%s' HAState %s", + saAisNameBorrow(&csi_desc.csiName), + ha_state_name[ha_state]); + + /* For debug log the CSI attributes, they could + ** define the workload characteristics */ + for (i = 0; i < csi_desc.csiAttr.number; i++) { + attr = &csi_desc.csiAttr.attr[i]; + syslog(LOG_DEBUG, " name: %s, value: %s", + attr->attrName, attr->attrValue); + } + + } else if (csi_desc.csiFlags == SA_AMF_CSI_TARGET_ALL) { + syslog(LOG_INFO, "CSI Set - HAState %s for all assigned CSIs", + ha_state_name[ha_state]); + } else { + syslog(LOG_INFO, "CSI Set - HAState %s for '%s'", + ha_state_name[ha_state], + saAisNameBorrow(&csi_desc.csiName)); + } + + switch (ha_state) { + case SA_AMF_HA_ACTIVE: + status = foo_activate(); + break; + case SA_AMF_HA_STANDBY: + /* + * Not much to do in this simple example code + * For real one could open a checkpoint for reads + * Open a communication channel for listening + * etc. + */ + status = 0; + break; + case SA_AMF_HA_QUIESCED: + /* the effect of admin op lock on SU or node or ... */ + status = foo_deactivate(); + break; + case SA_AMF_HA_QUIESCING: + /* the effect of admin op lock on SU or node or ... */ + status = 0; + break; + default: + syslog(LOG_ERR, "unmanaged HA state %u", ha_state); + status = -1; + break; + } + + if (status == 0) + error = SA_AIS_OK; + else + error = SA_AIS_ERR_FAILED_OPERATION; + + rc = saAmfResponse_4(contained_amf_hdl, invocation, 0, error); + if (rc != SA_AIS_OK) { + syslog(LOG_ERR, "saAmfResponse_4 FAILED - %u", rc); + exit(1); + } + + if (ha_state == SA_AMF_HA_QUIESCING) { + /* "gracefully quiescing CSI work assignment" */ + sleep(1); + rc = saAmfCSIQuiescingComplete(contained_amf_hdl, invocation, + SA_AIS_OK); + if (rc != SA_AIS_OK) { + syslog(LOG_ERR, "saAmfCSIQuiescingComplete FAILED - %u", + rc); + exit(1); + } + if (csi_desc.csiFlags == SA_AMF_CSI_TARGET_ONE) { + rc = saAmfHAStateGet(contained_amf_hdl, comp_name, + &csi_desc.csiName, + &contained_ha_state); + if (rc != SA_AIS_OK) { + syslog(LOG_ERR, "saAmfHAStateGet FAILED - %u", + rc); + exit(1); + } + } else if (csi_desc.csiFlags == SA_AMF_CSI_TARGET_ALL) { + // Application could iterate saAmfHAStateGet() for every + // csi which had been assigned to this component to + // ensure all csi(s) are QUIESCED + + // temporary set to QUIESCED + contained_ha_state = SA_AMF_HA_QUIESCED; + } + + syslog(LOG_INFO, "My HA state is %s", + ha_state_name[contained_ha_state]); + } +} + +/** + * AMF invokes this callback to remove a previously assigned workload. + * As a consequence of admin lock of the SU, a CSI would first get QUIESCED + * and then removed. + * See Figure 44, page 405 + * + * @param invocation + * @param comp_name + * @param csi_name + * @param csi_flags + */ +static void amf_csi_remove_callback(SaInvocationT invocation, + const SaNameT *comp_name, + const SaNameT *csi_name, + SaAmfCSIFlagsT csi_flags) +{ + SaAisErrorT rc; + + if (csi_flags == SA_AMF_CSI_TARGET_ALL) + syslog(LOG_INFO, "CSI Remove for all CSIs"); + else if (csi_flags == SA_AMF_CSI_TARGET_ONE) + syslog(LOG_INFO, "CSI Remove for '%s'", + saAisNameBorrow(csi_name)); + else + // A non valid case, see 7.9.3 + abort(); + + /* Reset the HA state */ + my_ha_state = 0; + + rc = saAmfResponse_4(my_amf_hdl, invocation, 0, SA_AIS_OK); + if (rc != SA_AIS_OK) { + syslog(LOG_ERR, "saAmfResponse_4 FAILED - %u", rc); + exit(1); + } +} + +static void contained_csi_remove_callback(SaInvocationT invocation, + const SaNameT *comp_name, + const SaNameT *csi_name, + SaAmfCSIFlagsT csi_flags) +{ + SaAisErrorT rc; + + if (csi_flags == SA_AMF_CSI_TARGET_ALL) + syslog(LOG_INFO, "CSI Remove for all CSIs"); + else if (csi_flags == SA_AMF_CSI_TARGET_ONE) + syslog(LOG_INFO, "CSI Remove for '%s'", + saAisNameBorrow(csi_name)); + else + // A non valid case, see 7.9.3 + abort(); + + /* Reset the HA state */ + contained_ha_state = 0; + + rc = saAmfResponse_4(contained_amf_hdl, invocation, 0, SA_AIS_OK); + if (rc != SA_AIS_OK) { + syslog(LOG_ERR, "saAmfResponse_4 FAILED - %u", rc); + exit(1); + } +} + +/** + * AMF invoked this callback periodically to assess our health. + * + * @param inv + * @param comp_name + * @param health_check_key + */ +static void amf_healthcheck_callback(SaInvocationT inv, + const SaNameT *comp_name, + SaAmfHealthcheckKeyT *health_check_key) +{ + SaAisErrorT rc, status = SA_AIS_OK; + static int healthcheck_count = 0; + + healthcheck_count++; + + syslog(LOG_DEBUG, "Health check %u", healthcheck_count); + + /* Check the status of our service but only if active */ + if ((my_ha_state == SA_AMF_HA_ACTIVE) && (foo_healthcheck() != 0)) { + /* 7.8.2 - an error report should be done before returning + * failed op */ + rc = saAmfComponentErrorReport(my_amf_hdl, &my_comp_name, 0, + SA_AMF_COMPONENT_RESTART, + SA_NTF_IDENTIFIER_UNUSED); + if (rc != SA_AIS_OK) { + syslog(LOG_ERR, "saAmfComponentErrorReport FAILED - %u", + rc); + exit(1); + } + status = SA_AIS_ERR_FAILED_OPERATION; + } + + rc = saAmfResponse_4(my_amf_hdl, inv, 0, status); + if (rc != SA_AIS_OK) { + syslog(LOG_ERR, "saAmfResponse_4 FAILED - %u", rc); + exit(1); + } +} + +static void contained_healthcheck_callback(SaInvocationT inv, + const SaNameT *comp_name, + SaAmfHealthcheckKeyT *health_check_key) +{ + SaAisErrorT rc, status = SA_AIS_OK; + static int healthcheck_count = 0; + + healthcheck_count++; + + syslog(LOG_DEBUG, "Health check %u", healthcheck_count); + + /* Check the status of our service but only if active */ + if ((contained_ha_state == SA_AMF_HA_ACTIVE) && (foo_healthcheck() != 0)) { + /* 7.8.2 - an error report should be done before returning + * failed op */ + rc = saAmfComponentErrorReport(contained_amf_hdl, + &my_comp_name, 0, + SA_AMF_COMPONENT_RESTART, + SA_NTF_IDENTIFIER_UNUSED); + if (rc != SA_AIS_OK) { + syslog(LOG_ERR, "saAmfComponentErrorReport FAILED - %u", + rc); + exit(1); + } + status = SA_AIS_ERR_FAILED_OPERATION; + } + + rc = saAmfResponse_4(contained_amf_hdl, inv, 0, status); + if (rc != SA_AIS_OK) { + syslog(LOG_ERR, "saAmfResponse_4 FAILED - %u", rc); + exit(1); + } +} + +/** + * AMF invokes this callback as a consequence of admin operations + * such as SU or node lock-instantiation. + * + * @param inv + * @param comp_name + */ +static void amf_comp_terminate_callback(SaInvocationT inv, + const SaNameT *comp_name) +{ + SaAisErrorT rc; + + syslog(LOG_NOTICE, "Terminating"); + + rc = saAmfResponse_4(my_amf_hdl, inv, 0, SA_AIS_OK); + if (rc != SA_AIS_OK) { + syslog(LOG_ERR, "saAmfResponse_4 FAILED - %u", rc); + exit(1); + } + + exit(0); +} + +/** + * AMF invokes this callback as a consequence of change in + * csi attribute value. + * @param inv + * @param csi_name + * @param csiAttr + */ + +/*static void amf_csi_attr_change_callback(SaInvocationT invocation, + const SaNameT *csi_name, + SaAmfCSIAttributeListT csiAttr) +{ + SaAisErrorT rc; + SaAmfCSIAttributeT *attr; + static int i; + syslog(LOG_INFO, "=====CSI Attr Change====>"); + + syslog(LOG_INFO, "CSI----->:'%s'", saAisNameBorrow(csi_name)); + for (i = 0; i < csiAttr.number; i++) { + attr = &csiAttr.attr[i]; + syslog(LOG_INFO, "CSIATTR--->: %s, val--->: %s", attr->attrName, + attr->attrValue); + } + rc = saAmfResponse_4(my_amf_hdl, invocation, 0, SA_AIS_OK); + if (rc != SA_AIS_OK) { + syslog(LOG_ERR, "saAmfResponse_4 FAILED - %u", rc); + exit(1); + } + syslog(LOG_INFO, "<================="); +}*/ +static void contained_component_instantiate_callback(SaInvocationT invocation, + const SaNameT *containedCompName) +{ + SaAisErrorT rc, response = SA_AIS_OK; + static bool init = false; + + syslog(LOG_INFO, "=====Contained Instantiate Callback====>"); + syslog(LOG_INFO, " comp:%s", saAisNameBorrow(containedCompName)); + + if (!init) { + init = true; + response = SA_AIS_ERR_TRY_AGAIN; + syslog(LOG_INFO, "responding with TRY_AGAIN"); + } + + if (response != SA_AIS_OK) { + rc = saAmfComponentRegister(contained_amf_hdl, + containedCompName, NULL); + if (rc != SA_AIS_OK) { + syslog(LOG_ERR, "saAmfComponentRegister FAILED - %u", + rc); + exit(1); + } + } + + rc = saAmfResponse_4(my_amf_hdl, invocation, 0, response); + if (rc != SA_AIS_OK) { + syslog(LOG_ERR, "saAmfResponse_4 FAILED - %u", rc); + exit(1); + } + + syslog(LOG_INFO, "<==========================================="); + +} + +static void contained_component_cleanup_callback(SaInvocationT invocation, + const SaNameT *containedCompName) +{ + SaAisErrorT rc; + syslog(LOG_INFO, "=====Contained Clean Up Callback====>"); + syslog(LOG_INFO, " comp:%s", saAisNameBorrow(containedCompName)); + rc = saAmfResponse_4(my_amf_hdl, invocation, 0, SA_AIS_OK); + if (rc != SA_AIS_OK) { + syslog(LOG_ERR, "saAmfResponse_4 FAILED - %u", rc); + exit(1); + } + syslog(LOG_INFO, "<==========================================="); + +} + +static void contained_terminate_callback(SaInvocationT inv, + const SaNameT *comp_name) +{ + SaAisErrorT rc; + + syslog(LOG_INFO, "=====Contained Terminate Callback====>"); + syslog(LOG_NOTICE, " comp:'%s'", saAisNameBorrow(comp_name)); + + rc = saAmfResponse_4(contained_amf_hdl, inv, 0, SA_AIS_OK); + if (rc != SA_AIS_OK) { + syslog(LOG_ERR, "saAmfResponse_4 FAILED - %u", rc); + exit(1); + } + syslog(LOG_INFO, "<====================================="); +} + +/** + * Create a PID file in directory + * + * @param directory + * @param filename_prefix + */ +static void create_pid_file(const char *directory, const char *filename_prefix) +{ + char path[256]; + FILE *fp; + + snprintf(path, sizeof(path), "%s/%s.pid", directory, filename_prefix); + + fp = fopen(path, "w"); + if (fp == NULL) { + syslog(LOG_ERR, "fopen '%s' failed: %s", path, strerror(errno)); + exit(EXIT_FAILURE); + } + fprintf(fp, "%d\n", getpid()); + fclose(fp); +} + +/** + * Our TERM signal handler + * @param sig + */ +static void sigterm_handler(int sig) +{ + /* Don't log in a signal handler! But we're exiting anyway... */ + syslog(LOG_NOTICE, "exiting (caught term signal)"); + exit(EXIT_SUCCESS); +} + +/** + * Initialize with AMF + * @param amf_sel_obj [out] + * + * @return SaAisErrorT + */ +static SaAisErrorT amf_initialize(SaSelectionObjectT *amf_sel_obj) +{ + SaAisErrorT rc; + SaAmfCallbacksT_4 amf_callbacks = {0}; + SaVersionT api_ver = {.releaseCode = 'B', + api_ver.majorVersion = 0x04, + api_ver.minorVersion = 0x01}; + + /* Initialize our callbacks */ + amf_callbacks.saAmfCSISetCallback = amf_csi_set_callback; + amf_callbacks.saAmfCSIRemoveCallback = amf_csi_remove_callback; + amf_callbacks.saAmfHealthcheckCallback = amf_healthcheck_callback; + amf_callbacks.saAmfComponentTerminateCallback = + amf_comp_terminate_callback; + amf_callbacks.saAmfContainedComponentInstantiateCallback = + contained_component_instantiate_callback; + amf_callbacks.saAmfContainedComponentCleanupCallback = + contained_component_cleanup_callback; + + + rc = saAmfInitialize_4(&my_amf_hdl, &amf_callbacks, &api_ver); + if (rc != SA_AIS_OK) { + syslog(LOG_ERR, " saAmfInitialize FAILED %u", rc); + goto done; + } + + rc = saAmfSelectionObjectGet(my_amf_hdl, amf_sel_obj); + if (rc != SA_AIS_OK) { + syslog(LOG_ERR, "saAmfSelectionObjectGet FAILED %u", rc); + goto done; + } + + rc = saAmfComponentNameGet(my_amf_hdl, &my_comp_name); + if (rc != SA_AIS_OK) { + syslog(LOG_ERR, "saAmfComponentNameGet FAILED %u", rc); + goto done; + } + + syslog(LOG_INFO, "before saAmfComponentRegister [%s]", + saAisNameBorrow(&my_comp_name)); + rc = saAmfComponentRegister(my_amf_hdl, &my_comp_name, 0); + syslog(LOG_INFO, "after saAmfComponentRegister "); + if (rc != SA_AIS_OK) { + syslog(LOG_ERR, "saAmfComponentRegister FAILED %u", rc); + goto done; + } + + /*rc = saAmfHealthcheckStart( + my_amf_hdl, &my_comp_name, &my_healthcheck_key, + SA_AMF_HEALTHCHECK_AMF_INVOKED, SA_AMF_COMPONENT_RESTART); + if (rc != SA_AIS_OK) { + syslog(LOG_ERR, "saAmfHealthcheckStart FAILED - %u", rc); + goto done; + }*/ +done: + return rc; +} + +static int getMD5Code(const char *str, char *md5_sum) +{ + char cmd[2048]; + FILE *pipe; + int i, ch; + + sprintf(cmd, "echo %s | md5sum | awk '{print $1}' 2>/dev/null", str); + pipe = popen(cmd, "r"); + if (pipe == NULL) + return 0; + + for (i = 0; i < MD5_LEN && isxdigit(ch = fgetc(pipe)); i++) { + *md5_sum++ = ch; + } + + *md5_sum = '\0'; + pclose(pipe); + return i == MD5_LEN; +} +static SaAisErrorT contained_initialize(SaSelectionObjectT *amf_sel_obj) +{ + SaAisErrorT rc; + SaAmfCallbacksT_4 amf_callbacks = {0}; + SaVersionT api_ver = {.releaseCode = 'B', + api_ver.majorVersion = 0x04, + api_ver.minorVersion = 0x01}; + + /* Initialize our callbacks */ + amf_callbacks.saAmfCSISetCallback = contained_csi_set_callback; + amf_callbacks.saAmfCSIRemoveCallback = contained_csi_remove_callback; + amf_callbacks.saAmfHealthcheckCallback = contained_healthcheck_callback; + amf_callbacks.saAmfComponentTerminateCallback = contained_terminate_callback; + + rc = saAmfInitialize_4(&contained_amf_hdl, &amf_callbacks, &api_ver); + if (rc != SA_AIS_OK) { + syslog(LOG_ERR, " saAmfInitialize FAILED %u", rc); + goto done; + } + + rc = saAmfSelectionObjectGet(contained_amf_hdl, amf_sel_obj); + if (rc != SA_AIS_OK) { + syslog(LOG_ERR, "saAmfSelectionObjectGet FAILED %u", rc); + goto done; + } +done: + return rc; +} +int main(int argc, char **argv) +{ + SaAisErrorT rc; + SaSelectionObjectT amf_sel_obj, contained_sel_obj; + struct pollfd fds[2]; + char *env_comp_name; + char md5[MD5_LEN + 1]; + /* Environment variable "SA_AMF_COMPONENT_NAME" exist when started by + * AMF */ + if ((env_comp_name = getenv("SA_AMF_COMPONENT_NAME")) == NULL) { + fprintf(stderr, "not started by AMF exiting...\n"); + exit(EXIT_FAILURE); + } + + /* Daemonize ourselves and detach from terminal. + ** This important since our start script will hang forever otherwise. + ** Note daemon() is not LSB but impl by libc so fairly portable... + */ + if (daemon(0, 1) == -1) { + syslog(LOG_ERR, "daemon failed: %s", strerror(errno)); + goto done; + } + /* Install a TERM handler just to log and visualize when cleanup is + * called */ + if ((signal(SIGTERM, sigterm_handler)) == SIG_ERR) { + syslog(LOG_ERR, "signal TERM failed: %s", strerror(errno)); + goto done; + } + + /* Create a PID file which is needed by our CLC-CLI script. + ** Use AMF component name as file name so multiple instances of this + ** component can be managed by the same script. + */ + // This is a temporary solution to overcome the limit of linux in + // filename length (255) + // create_pid_file("/tmp", env_comp_name); + if (!getMD5Code(env_comp_name, md5)) { + syslog(LOG_ERR, "failed to get the hash code of comp: %s", + env_comp_name); + goto done; + } + + // Create a file with the hashed name + create_pid_file("/tmp", md5); + + // Enable long DN + if (setenv("SA_ENABLE_EXTENDED_NAMES", "1", 1)) { + syslog(LOG_ERR, "failed to set SA_ENABLE_EXTENDED_NAMES"); + } + + /* Use syslog for logging */ + openlog(basename(argv[0]), LOG_PID, LOG_USER); + + /* Make a log to associate component name with PID */ + syslog(LOG_INFO, "'%s' started", env_comp_name); + + if (amf_initialize(&amf_sel_obj) != SA_AIS_OK) + goto done; + + if (contained_initialize(&contained_sel_obj) != SA_AIS_OK) + goto done; + + syslog(LOG_INFO, "Registered with AMF and HC started"); + + fds[0].fd = amf_sel_obj; + fds[0].events = POLLIN; + fds[1].fd = contained_sel_obj; + fds[1].events = POLLIN; + + /* Loop forever waiting for events on watched file descriptors */ + while (1) { + int res = poll(fds, 2, -1); + + if (res == -1) { + if (errno == EINTR) + continue; + else { + syslog(LOG_ERR, "poll FAILED - %s", + strerror(errno)); + goto done; + } + } + + if (fds[0].revents & POLLIN) { + rc = saAmfDispatch(my_amf_hdl, SA_DISPATCH_ONE); + if (rc != SA_AIS_OK) { + syslog(LOG_ERR, "saAmfDispatch FAILED %u", rc); + goto done; + } + } + if (fds[1].revents & POLLIN) { + rc = saAmfDispatch(contained_amf_hdl, SA_DISPATCH_ONE); + if (rc != SA_AIS_OK) { + syslog(LOG_ERR, "saAmfDispatch FAILED %u", rc); + goto done; + } + } + } + +done: + return EXIT_FAILURE; +} diff --git a/samples/amf/container/amf_container_script b/samples/amf/container/amf_container_script new file mode 100755 index 000000000..682a3d1fe --- /dev/null +++ b/samples/amf/container/amf_container_script @@ -0,0 +1,101 @@ +#!/bin/sh +# +# -*- OpenSAF -*- +# +# (C) Copyright 2008 The OpenSAF Foundation +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +# or FITNESS FOR A PARTICULAR PURPOSE. This file and program are licensed +# under the GNU Lesser General Public License Version 2.1, February 1999. +# The complete license can be accessed from the following location: +# http://opensource.org/licenses/lgpl-license.php +# See the Copying file included with the OpenSAF distribution for full +# licensing terms. +# +# Author(s): Emerson Network Power, Erisson +# + +name=$(basename $0) + +if [ -z $SA_AMF_COMPONENT_NAME ]; then + logger -st $name "not AMF component context" + exit 199 +fi + +prog="amf_container_demo" +binary=/opt/amf_demo/$prog + +if ! [ -x $binary ]; then + logger -st $name "$binary not executable" + exit 198 +fi + +# Source LSB functions library +. /lib/lsb/init-functions + +piddir="/tmp" +compname=`echo $SA_AMF_COMPONENT_NAME | md5sum | awk '{print $1}'` +pidfile="$piddir/${compname}.pid" +logger "CONTAINED COMP NAME:$AMF_CONTAINER1" + +export AVA_TRACE_PATHNAME="/tmp/ava.trace" +#MEMTOOL="/usr/bin/valgrind --leak-check=full --log-file=/tmp/ava.valgrind" + +RETVAL=0 + +start() +{ + args="$*" + echo -n "Starting $prog: " + start_daemon -p $pidfile $binary $args + RETVAL=$? + if [ $RETVAL -ne 0 ]; then + logger -st $name "Starting $binary failed" + fi + return $RETVAL +} + +stop() +{ + echo -n "Stopping $prog: " + killproc -p $pidfile $binary + RETVAL=$? + if [ $RETVAL -ne 0 ]; then + logger -st $name "killproc $binary failed" + fi + return $RETVAL +} + +status() +{ + pidofproc -p $pidfile $binary + RETVAL=$? + return $RETVAL +} + +CMD=$1 +case $CMD in + start|instantiate) + shift + start $* + RETVAL=$? + ;; + stop|cleanup) + stop $* + RETVAL=$? + ;; + cleanup_contained) + RETVAL=0 + ;; + status) + status + RETVAL=$? + ;; + *) + echo "Usage: $0 {instantiate|cleanup}" + RETVAL=2 +esac + +exit $RETVAL + diff --git a/samples/configure.ac b/samples/configure.ac index 7cf803e7d..281edc5c8 100644 --- a/samples/configure.ac +++ b/samples/configure.ac @@ -67,6 +67,7 @@ AC_CONFIG_FILES([ \ amf/wrapper/Makefile \ amf/proxy/Makefile \ amf/api_demo/Makefile \ + amf/container/Makefile \ cpsv/Makefile \ cpsv/ckpt_demo/Makefile \ cpsv/ckpt_track_demo/Makefile \ diff --git a/tools/cluster_sim_uml/build_uml b/tools/cluster_sim_uml/build_uml index 16d49d03e..d2cad276f 100755 --- a/tools/cluster_sim_uml/build_uml +++ b/tools/cluster_sim_uml/build_uml @@ -121,6 +121,50 @@ cmd_install_testprog() { cmd_mkcpio } +cmd_build_container_testprog() { + src=$opensaf_home/samples/amf/container + libd=$root/usr/local/$lib_dir + installd=$root/opt/amf_demo + + mkdir -p "$installd" + cp $src/amf_container_script $installd + gcc -g -O2 -Wall -fPIC -I$opensaf_home/src/amf/saf \ + -I$opensaf_home/src/ais/include \ + -DSA_EXTENDED_NAME_SOURCE \ + -o $installd/amf_container_demo $src/amf_container_demo.c \ + -Wl,--as-needed "-Wl,-rpath-link,$libd:$libd/opensaf" "-L$libd" -lSaAmf -lopensaf_core + + echo "Creating [$root/root.cpio] ..." + cmd_mkcpio +} + +## install_container_testprog +## Build and install the AMF container demo program. +## +cmd_install_container_testprog() { + src=$opensaf_home/samples/amf/container + libd=$root/usr/local/$lib_dir + installd=$root/opt/amf_demo + immxml=$root/etc/opensaf/imm.xml + containedXml=$src/AppConfig-contained-2N.xml + containerXml=$src/AppConfig-container.xml + + mkdir -p $installd + cp $src/amf_container_script $installd + gcc -g -O2 -Wall -fPIC -I$opensaf_home/src/amf/saf \ + -I$opensaf_home/src/ais/include \ + -DSA_EXTENDED_NAME_SOURCE \ + -o $installd/amf_container_demo $src/amf_container_demo.c \ + -Wl,--as-needed "-Wl,-rpath-link,$libd:$libd/opensaf" "-L$libd" -lSaAmf + + test -r $immxml.orig || cp $immxml $immxml.orig + $opensaf_home/src/imm/tools/immxml-merge \ + $immxml.orig $containedXml $containerXml > $immxml + $opensaf_home/src/imm/tools/immxml-validate $immxml + echo "Creating [$root/root.cpio] ..." + cmd_mkcpio +} + ## create_rootfs ## Create a (shadow) rootfs with OpenSAF and other required programs. ## @@ -175,6 +219,7 @@ cmd_create_rootfs() test -e /usr/bin/strace && install /usr/bin/strace usr/bin test -e /usr/bin/lsof && install /usr/bin/lsof usr/bin test -e /bin/pidof && install /bin/pidof usr/bin + test -e /bin/prlimit && install /bin/prlimit usr/bin test -e /usr/sbin/tcpdump && install /usr/sbin/tcpdump usr/sbin test -e /usr/bin/addr2line && install /usr/bin/addr2line usr/bin if test -e /usr/bin/gdb; then -- 2.14.4 ------------------------------------------------------------------------------ Check out the vibrant tech community on one of the world's most engaging tech sites, Slashdot.org! http://sdm.link/slashdot _______________________________________________ Opensaf-devel mailing list Opensaf-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/opensaf-devel