On 02/04/2014 08:23 AM, Nagendra Kumar wrote:
> Ack with comments.
>
> 1. Please change name of init_clc_cli_commands to
> init_clc_cli_commands_and_timeouts.
Gets a bit long, how about init_clc_cli_attributes?
> 2. If I am configuring saAmfCtRelPathInstantiateCmd with relative patch
> (/opt/amf_demo) and also configure
^^^^^^^^^^^^^^ you
mean abspath?
> saAmfCtSwBundle, then it is only taking saAmfCtRelPathInstantiateCmd. This
> need to be documented.
yes the AMF PR needs more updates, I plan to take a stab at it.
Thanks,
Hans
>
> Thanks -Nagu
>
>> -----Original Message----- From: Hans Feldt [mailto:[email protected]]
>> Sent: 28 January 2014 19:11 To: Nagendra
>> Kumar Cc: [email protected] Subject: [PATCH 2 of 2] amfnd:
>> ignore saAmfCtSwBundle when abspath in
>> CLC- CLI cmds [#662]
>>
>> osaf/services/saf/amf/amfnd/compdb.cc | 290
>> ++++++++++++-------------------- - 1 files changed, 108 insertions(+),
>> 182 deletions(-)
>>
>>
>> diff --git a/osaf/services/saf/amf/amfnd/compdb.cc
>> b/osaf/services/saf/amf/amfnd/compdb.cc ---
>> a/osaf/services/saf/amf/amfnd/compdb.cc +++
>> b/osaf/services/saf/amf/amfnd/compdb.cc @@ -956,10 +956,10 @@ static
>> amf_comp_type_t *avnd_comptype_cr if
>> (immutil_getAttr(const_cast<SaImmAttrNameT>("saAmfCtCompCategory"),
>> attributes, 0, &compt->saAmfCtCompCategory) != SA_AIS_OK) osafassert(0);
>>
>> - if (IS_COMP_LOCAL(compt->saAmfCtCompCategory) && -
>> immutil_getAttr(const_cast<SaImmAttrNameT>("saAmfCtSwBundle"), attributes,
>> 0, &compt->saAmfCtSwBundle) !=
>> SA_AIS_OK) { - osafassert(0); - return NULL; +
>> if (IS_COMP_LOCAL(compt->saAmfCtCompCategory)) { + // Ignore if
>> bundle not found, commands can be absolute path +
>> immutil_getAttr(const_cast<SaImmAttrNameT>("saAmfCtSwBundle"), +
>> attributes, 0, &compt->saAmfCtSwBundle); }
>>
>>
>> immutil_getAttrValuesNumber(const_cast<SaImmAttrNameT>("saAmfCtDefCm dEnv"),
>> attributes, &j); @@ -1170,170
>> +1170,145 @@ done: }
>>
>> /** - * Initialize the bundle dependent attributes in comp (the - * CLC-CLI
>> commands). - * - * If path in comptype
>> for AM & HC scripts is absolute it is - * used, else (it is relative) it is
>> prepended with path prefix. + *
>> Initializes a single CLC-CLI command for a component. + * + * If path in
>> comptype is absolute it is used, else (it
>> is relative) it is + * prepended with path prefix. + * + * @param cmd + *
>> @param clc_cmd + * @param type_cmd_argv +
>> * @param path_prefix + * @param attributes + * @param attr_name + */ +static
>> void
>> init_clc_cli_command(AVND_COMP_CLC_CMD_PARAM *cmd, const char *clc_cmd, +
>> char **clc_cmd_argv, const char
>> *path_prefix, + const SaImmAttrValuesT_2 **attributes, +
>> const char *attr_name) +{ + char *buf = cmd->cmd; + int
>> i, j; + const char *argv; + + // prepend with path prefix (from
>> saAmfNodeSwBundlePathPrefix) if needed + if
>> (clc_cmd[0] == '/') + i = snprintf(buf, sizeof(cmd->cmd),
>> "%s", clc_cmd); + else + i = snprintf(buf,
>> sizeof(cmd->cmd), "%s/%s", path_prefix, clc_cmd); + + // append argv
>> from comp type + j = 0; + while ((argv =
>> clc_cmd_argv[j++]) != NULL) + i += snprintf(&buf[i],
>> sizeof(cmd->cmd) - i, " %s", argv); + + // append argv from
>> comp instance + j = 0; + while ((argv =
>> immutil_getStringAttr(attributes, attr_name, j++)) != NULL) + i +=
>> snprintf(&buf[i], sizeof(cmd->cmd) - i, " %s", argv); + + cmd->len = i; +
>> + /* Check for truncation, should alloc
>> these strings dynamically instead */ + osafassert((cmd->len > 0) &&
>> (cmd->len < sizeof(cmd->cmd))); +
>> TRACE("cmd=%s", cmd->cmd); +} + +/** + * Initializes the CLC-CLI commands
>> for a component. * * @param comp * @param
>> comptype * @param path_prefix * @param attributes */ -static void
>> init_bundle_dependent_attributes(AVND_COMP
>> *comp, +static void init_clc_cli_commands(AVND_COMP *comp, const
>> amf_comp_type_t *comptype, const char
>> *path_prefix, const SaImmAttrValuesT_2 **attributes) { - int i, j;
>> AVND_COMP_CLC_CMD_PARAM *cmd; - const char
>> *argv; + TRACE_ENTER();
>>
>> cmd = &comp-
>>> clc_info.cmds[AVND_COMP_CLC_CMD_TYPE_INSTANTIATE - 1];
>> if (comptype->saAmfCtRelPathInstantiateCmd != NULL) { - i = 0;
>> - i += snprintf(&cmd->cmd[i], sizeof(cmd->cmd) -
>> i, "%s/%s", - path_prefix, comptype-
>>> saAmfCtRelPathInstantiateCmd);
>> + init_clc_cli_command(cmd, comptype-
>>> saAmfCtRelPathInstantiateCmd,
>> + comptype->saAmfCtDefInstantiateCmdArgv,
>> path_prefix, + attributes,
>> "saAmfCompInstantiateCmdArgv"); + }
>>
>> - j = 0; - while ((argv = comptype-
>>> saAmfCtDefInstantiateCmdArgv[j++]) != NULL)
>> - i += snprintf(&cmd->cmd[i], sizeof(cmd->cmd) - i, "
>> %s", argv); - - j = 0; - while ((argv =
>> immutil_getStringAttr(attributes, "saAmfCompInstantiateCmdArgv", j++)) !=
>> NULL) - i += snprintf(&cmd->cmd[i],
>> sizeof(cmd->cmd) - i, " %s", argv); - - cmd->len = i; - -
>> /* Check for truncation, should alloc these strings
>> dynamically instead */ - osafassert((cmd->len > 0) && (cmd->len
>> < sizeof(cmd->cmd))); - TRACE("cmd=%s",
>> cmd->cmd); + if
>> (immutil_getAttr(const_cast<SaImmAttrNameT>("saAmfCompInstantiateTimeo ut"),
>> + attributes, 0,
>> &cmd->timeout) != SA_AIS_OK) { + cmd->timeout =
>> comptype->saAmfCtDefClcCliTimeout; + comp->pxied_inst_cbk_timeout
>> = comptype-
>>> saAmfCtDefCallbackTimeout;
>> + } else { + comp->pxied_inst_cbk_timeout = cmd->timeout; }
>>
>> cmd = &comp-
>>> clc_info.cmds[AVND_COMP_CLC_CMD_TYPE_TERMINATE - 1];
>> if (comptype->saAmfCtRelPathTerminateCmd != NULL) { - i = 0;
>> - i += snprintf(&cmd->cmd[i], sizeof(cmd->cmd) - i,
>> "%s/%s", - path_prefix, comptype-
>>> saAmfCtRelPathTerminateCmd);
>> + init_clc_cli_command(cmd, comptype-
>>> saAmfCtRelPathTerminateCmd,
>> + comptype->saAmfCtDefTerminateCmdArgv,
>> path_prefix, + attributes,
>> "saAmfCompTerminateCmdArgv"); + }
>>
>> - j = 0; - while ((argv =
>> comptype->saAmfCtDefTerminateCmdArgv[j++]) != NULL) - i
>> += snprintf(&cmd->cmd[i],
>> sizeof(cmd->cmd) - i, " %s", argv); - - j = 0; -
>> while ((argv = immutil_getStringAttr(attributes,
>> "saAmfCompTerminateCmdArgv", j++)) != NULL) - i +=
>> snprintf(&cmd->cmd[i], sizeof(cmd->cmd) - i, " %s", argv); - -
>> cmd->len = i; - - /* Check for truncation, should alloc these
>> strings dynamically instead */ -
>> osafassert((cmd->len > 0) && (cmd->len < sizeof(cmd->cmd))); -
>> TRACE("cmd=%s", cmd->cmd); + if
>> (immutil_getAttr(const_cast<SaImmAttrNameT>("saAmfCompTerminateTimeo ut"), +
>> attributes, 0, &cmd->timeout) !=
>> SA_AIS_OK) { + if (m_AVND_COMP_TYPE_IS_PREINSTANTIABLE(comp))
>> { + cmd->timeout = comptype-
>>> saAmfCtDefCallbackTimeout;
>> + comp->term_cbk_timeout = cmd->timeout; +
>> } + else + cmd->timeout =
>> comptype->saAmfCtDefClcCliTimeout; }
>>
>> cmd = &comp-
>>> clc_info.cmds[AVND_COMP_CLC_CMD_TYPE_CLEANUP - 1];
>> if (comptype->saAmfCtRelPathCleanupCmd != NULL) { - i = 0; -
>> i += snprintf(&cmd->cmd[i], sizeof(cmd->cmd) - i,
>> "%s/%s", - path_prefix,
>> comptype->saAmfCtRelPathCleanupCmd); + init_clc_cli_command(cmd,
>> comptype-
>>> saAmfCtRelPathCleanupCmd,
>> + comptype->saAmfCtDefCleanupCmdArgv,
>> path_prefix, + attributes,
>> "saAmfCompCleanupCmdArgv"); + }
>>
>> - j = 0; - while ((argv =
>> comptype->saAmfCtDefCleanupCmdArgv[j++]) != NULL) - i
>> += snprintf(&cmd->cmd[i],
>> sizeof(cmd->cmd) - i, " %s", argv); - - j = 0; -
>> while ((argv = immutil_getStringAttr(attributes,
>> "saAmfCompCleanupCmdArgv", j++)) != NULL) - i +=
>> snprintf(&cmd->cmd[i], sizeof(cmd->cmd) - i, " %s", argv); - -
>> cmd->len = i; - - /* Check for truncation, should alloc these
>> strings dynamically instead */ -
>> osafassert((cmd->len > 0) && (cmd->len < sizeof(cmd->cmd))); -
>> TRACE("cmd=%s", cmd->cmd); + if
>> (immutil_getAttr(const_cast<SaImmAttrNameT>("saAmfCompCleanupTimeout" ), +
>> attributes, 0, &cmd->timeout) !=
>> SA_AIS_OK) { + cmd->timeout =
>> comptype->saAmfCtDefClcCliTimeout; +
>> comp->pxied_clean_cbk_timeout = comptype-
>>> saAmfCtDefCallbackTimeout;
>> + } else { + comp->pxied_clean_cbk_timeout = cmd->timeout; }
>>
>> cmd = &comp-
>>> clc_info.cmds[AVND_COMP_CLC_CMD_TYPE_AMSTART - 1];
>> if (comptype->saAmfCtRelPathAmStartCmd != NULL) { - i = 0; +
>> init_clc_cli_command(cmd, comptype-
>>> saAmfCtRelPathAmStartCmd,
>> + comptype->saAmfCtDefAmStartCmdArgv,
>> path_prefix, + attributes,
>> "saAmfCompAmStartCmdArgv"); +
>> comp->is_am_en = true; + }
>>
>> - if (comptype->saAmfCtRelPathAmStartCmd[0] == '/') -
>> i += snprintf(&cmd->cmd[i], sizeof(cmd->cmd) - i, "%s", -
>> comptype->saAmfCtRelPathAmStartCmd); - else -
>> i += snprintf(&cmd->cmd[i], sizeof(cmd->cmd) - i, "%s/%s", -
>> path_prefix, comptype-
>>> saAmfCtRelPathAmStartCmd);
>> - - j = 0; - while ((argv =
>> comptype->saAmfCtDefAmStartCmdArgv[j++]) != NULL) - i
>> += snprintf(&cmd->cmd[i],
>> sizeof(cmd->cmd) - i, " %s", argv); - - j = 0; -
>> while ((argv = immutil_getStringAttr(attributes,
>> "saAmfCompAmStartCmdArgv", j++)) != NULL) - i +=
>> snprintf(&cmd->cmd[i], sizeof(cmd->cmd) - i, " %s", argv); - -
>> cmd->len = i; - - comp->is_am_en = true; - - /*
>> Check for truncation, should alloc these strings dynamically
>> instead */ - osafassert((cmd->len > 0) && (cmd->len <
>> sizeof(cmd->cmd))); - TRACE("cmd=%s", cmd->cmd); + if
>> (immutil_getAttr(const_cast<SaImmAttrNameT>("saAmfCompAmStartTimeout "), +
>> attributes, 0, &cmd->timeout) !=
>> SA_AIS_OK) { + cmd->timeout =
>> comptype->saAmfCtDefClcCliTimeout; }
>>
>> cmd = &comp-
>>> clc_info.cmds[AVND_COMP_CLC_CMD_TYPE_AMSTOP - 1];
>> if (comptype->saAmfCtRelPathAmStopCmd != NULL) { - i = 0; +
>> init_clc_cli_command(cmd, comptype-
>>> saAmfCtRelPathAmStopCmd,
>> + comptype->saAmfCtDefAmStopCmdArgv, path_prefix,
>> + attributes, "saAmfCompAmStopCmdArgv"); +
>> }
>>
>> - if (comptype->saAmfCtRelPathAmStopCmd[0] == '/') -
>> i += snprintf(&cmd->cmd[i], sizeof(cmd->cmd) - i, "%s", -
>> comptype->saAmfCtRelPathAmStopCmd); - else -
>> i += snprintf(&cmd->cmd[i], sizeof(cmd->cmd) - i, "%s/%s", -
>> path_prefix, comptype-
>>> saAmfCtRelPathAmStopCmd);
>> - - j = 0; - while ((argv =
>> comptype->saAmfCtDefAmStopCmdArgv[j++]) != NULL) - i
>> += snprintf(&cmd->cmd[i],
>> sizeof(cmd->cmd) - i, " %s", argv); - - j = 0; -
>> while ((argv = immutil_getStringAttr(attributes,
>> "saAmfCompAmStopCmdArgv", j++)) != NULL) - i +=
>> snprintf(&cmd->cmd[i], sizeof(cmd->cmd) - i, " %s", argv); - -
>> cmd->len = i; - - /* Check for truncation, should alloc these
>> strings dynamically instead */ -
>> osafassert((cmd->len > 0) && (cmd->len < sizeof(cmd->cmd))); -
>> TRACE("cmd=%s", cmd->cmd); + if
>> (immutil_getAttr(const_cast<SaImmAttrNameT>("saAmfCompAmStopTimeout" ), +
>> attributes, 0, &cmd->timeout) !=
>> SA_AIS_OK) { + cmd->timeout =
>> comptype->saAmfCtDefClcCliTimeout; }
>>
>> cmd = &comp->clc_info.cmds[AVND_COMP_CLC_CMD_TYPE_HC - 1]; if
>> (comptype->osafAmfCtRelPathHcCmd != NULL) { - i =
>> 0; - - if (comptype->osafAmfCtRelPathHcCmd[0] == '/') -
>> i += snprintf(&cmd->cmd[i], sizeof(cmd->cmd) - i, "%s",
>> - comptype->osafAmfCtRelPathHcCmd); -
>> else - i += snprintf(&cmd->cmd[i], sizeof(cmd->cmd) - i,
>> "%s/%s", -
>> path_prefix, comptype-
>>> osafAmfCtRelPathHcCmd);
>> - - j = 0; - while ((argv =
>> comptype->osafAmfCtDefHcCmdArgv[j++]) != NULL) - i +=
>> snprintf(&cmd->cmd[i],
>> sizeof(cmd->cmd) - i, " %s", argv); - - j = 0; -
>> while ((argv = immutil_getStringAttr(attributes,
>> "osafAmfCompHcCmdArgv", j++)) != NULL) - i +=
>> snprintf(&cmd->cmd[i], sizeof(cmd->cmd) - i, " %s", argv); - -
>> cmd->len = i; - + init_clc_cli_command(cmd, comptype-
>>> osafAmfCtRelPathHcCmd,
>> + comptype->osafAmfCtDefHcCmdArgv, path_prefix, +
>> attributes, "osafAmfCompHcCmdArgv");
>> comp->is_hc_cmd_configured = true; - - /* Check for
>> truncation, should alloc these strings dynamically instead */
>> - osafassert((cmd->len > 0) && (cmd->len < sizeof(cmd->cmd))); -
>> TRACE("cmd=%s", cmd->cmd); }
>>
>> TRACE_LEAVE(); @@ -1344,16 +1319,12 @@ static void
>> init_bundle_dependent_attrib * * @param comp * @param
>> attributes - * @param bundle_missing_is_error if true skip further
>> initialization and return error code. - * if
>> false continue initialization to get most attributes correct. * * @return
>> int */ -static int comp_init(AVND_COMP
>> *comp, const SaImmAttrValuesT_2 **attributes, - bool
>> bundle_missing_is_error) +static int comp_init(AVND_COMP
>> *comp, const SaImmAttrValuesT_2 **attributes) { int res = -1; -
>> AVND_COMP_CLC_CMD_PARAM *cmd; amf_comp_type_t
>> *comptype; SaNameT nodeswbundle_name; SaBoolT disable_restart; @@ -1380,30
>> +1351,11 @@ static int
>> comp_init(AVND_COMP *comp, co
>> avsv_create_association_class_dn(&comptype->saAmfCtSwBundle,
>> &avnd_cb->amf_nodeName,
>> "safInstalledSwBundle", &nodeswbundle_name);
>>
>> - res = get_string_attr_from_imm(immOmHandle,
>> const_cast<SaImmAttrNameT>("saAmfNodeSwBundlePathPrefix"), + (void)
>> get_string_attr_from_imm(immOmHandle, +
>> const_cast<SaImmAttrNameT>("saAmfNodeSwBundlePathPrefix"),
>> &nodeswbundle_name, &path_prefix);
>>
>> - if (res == 0) { - init_bundle_dependent_attributes(comp,
>> comptype, path_prefix, attributes); - } else { - if
>> (bundle_missing_is_error) { - LOG_NO("%s: '%s'",
>> __FUNCTION__, comp-
>>> name.value);
>> - LOG_ER("%s: FAILED to read '%s'", __FUNCTION__,
>> nodeswbundle_name.value); - goto done; - }
>> else { -
>> TRACE("%s is missing, will refresh attributes later",
>> nodeswbundle_name.value); - /* Continue initialization to
>> get the correct type set. Especially - *
>> pre-instantiable or not is important when instantion request comes. */
>> - } - } - - cmd = &comp-
>>> clc_info.cmds[AVND_COMP_CLC_CMD_TYPE_INSTANTIATE - 1];
>> - if
>> (immutil_getAttr(const_cast<SaImmAttrNameT>("saAmfCompInstantiateTimeo ut"),
>> attributes, 0, &cmd->timeout) !=
>> SA_AIS_OK) { - cmd->timeout =
>> comptype->saAmfCtDefClcCliTimeout; -
>> comp->pxied_inst_cbk_timeout = comptype-
>>> saAmfCtDefCallbackTimeout;
>> - } else { - comp->pxied_inst_cbk_timeout = cmd->timeout; -
>> } + init_clc_cli_commands(comp, comptype, path_prefix,
>> attributes);
>>
>> if (immutil_getAttr(const_cast<SaImmAttrNameT>("saAmfCompInstantiationLeve
>> l"), attributes, 0, &comp->inst_level)
>> != SA_AIS_OK) comp->inst_level = comptype->saAmfCtDefInstantiationLevel; @@
>> -1423,26 +1375,10 @@ static int
>> comp_init(AVND_COMP *comp, co comp->inst_retry_delay =
>> comp_global_attrs.saAmfDelayBetweenInstantiateAttempts;
>> #endif
>>
>> - cmd = &comp-
>>> clc_info.cmds[AVND_COMP_CLC_CMD_TYPE_CLEANUP - 1];
>> - if
>> (immutil_getAttr(const_cast<SaImmAttrNameT>("saAmfCompCleanupTimeout" ),
>> attributes, 0, &cmd->timeout) !=
>> SA_AIS_OK) { - cmd->timeout =
>> comptype->saAmfCtDefClcCliTimeout; -
>> comp->pxied_clean_cbk_timeout = comptype-
>>> saAmfCtDefCallbackTimeout;
>> - } else { - comp->pxied_clean_cbk_timeout = cmd->timeout; -
>> } - - cmd = &comp-
>>> clc_info.cmds[AVND_COMP_CLC_CMD_TYPE_AMSTART - 1];
>> - if (immutil_getAttr(const_cast<SaImmAttrNameT>("saAmfCompAmStartTimeout
>> "), attributes, 0, &cmd->timeout) !=
>> SA_AIS_OK) - cmd->timeout = comptype->saAmfCtDefClcCliTimeout; - if
>> (immutil_getAttr(const_cast<SaImmAttrNameT>("saAmfCompNumMaxAmStart
>> Attempts"), attributes, 0,
>> &comp->clc_info.am_start_retry_max) != SA_AIS_OK)
>> comp->clc_info.am_start_retry_max =
>> comp_global_attrs.saAmfNumMaxAmStartAttempts;
>>
>> - cmd = &comp-
>>> clc_info.cmds[AVND_COMP_CLC_CMD_TYPE_AMSTOP - 1];
>> - if (immutil_getAttr(const_cast<SaImmAttrNameT>("saAmfCompAmStopTimeout"
>> ), attributes, 0, &cmd->timeout) !=
>> SA_AIS_OK) - cmd->timeout = comptype->saAmfCtDefClcCliTimeout; - if
>> (immutil_getAttr(const_cast<SaImmAttrNameT>("saAmfCompNumMaxAmStop
>> Attempts"), attributes, 0, &comp-
>>> clc_info.saAmfCompNumMaxAmStopAttempts) != SA_AIS_OK)
>> comp->clc_info.saAmfCompNumMaxAmStopAttempts =
>> comp_global_attrs.saAmfNumMaxAmStopAttempts; @@ -1476,16 +1412,6 @@
>> static int comp_init(AVND_COMP *comp, co
>>
>> init_comp_category(comp, comptype->saAmfCtCompCategory);
>>
>> - cmd = &comp-
>>> clc_info.cmds[AVND_COMP_CLC_CMD_TYPE_TERMINATE - 1];
>> - if (immutil_getAttr(const_cast<SaImmAttrNameT>("saAmfCompTerminateTimeo
>> ut"), attributes, 0, &cmd->timeout) !=
>> SA_AIS_OK) { - if (m_AVND_COMP_TYPE_IS_PREINSTANTIABLE(comp))
>> { - cmd->timeout = comptype-
>>> saAmfCtDefCallbackTimeout;
>> - comp->term_cbk_timeout = cmd->timeout; -
>> } - else - cmd->timeout =
>> comptype->saAmfCtDefClcCliTimeout; - }
>> - if (m_AVND_COMP_TYPE_IS_PREINSTANTIABLE(comp))
>> m_AVND_COMP_OPER_STATE_SET(comp, SA_AMF_OPERATIONAL_DISABLED);
>> else @@ -1598,7 +1524,7 @@ static AVND_COMP *avnd_comp_create(const error =
>> immutil_getAttr(const_cast<SaImmAttrNameT>("saAmfCompType"), attributes, 0,
>> &comp->saAmfCompType); osafassert(error
>> == SA_AIS_OK);
>>
>> - if (comp_init(comp, attributes, false) != 0) + if (comp_init(comp,
>> attributes) != 0) goto done;
>>
>> /* create the association with hdl-mngr */ @@ -1776,7 +1702,7 @@ int
>> avnd_comp_config_reinit(AVND_COMP *c goto
>> done2; }
>>
>> - res = comp_init(comp, attributes, true); + res = comp_init(comp,
>> attributes); if (res == 0) TRACE("'%s'
>> configuration reread from IMM", comp-
>>> name.value);
>>
>
> ------------------------------------------------------------------------------
> Managing the Performance of
> Cloud-Based Applications Take advantage of what the Cloud has to offer -
> Avoid Common Pitfalls. Read the Whitepaper.
> http://pubads.g.doubleclick.net/gampad/clk?id=121051231&iu=/4140/ostg.clktrk
> _______________________________________________ Opensaf-devel mailing list
> [email protected]
> https://lists.sourceforge.net/lists/listinfo/opensaf-devel
>
>
------------------------------------------------------------------------------
Managing the Performance of Cloud-Based Applications
Take advantage of what the Cloud has to offer - Avoid Common Pitfalls.
Read the Whitepaper.
http://pubads.g.doubleclick.net/gampad/clk?id=121051231&iu=/4140/ostg.clktrk
_______________________________________________
Opensaf-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/opensaf-devel