Hi Anders,

thanks, I'll fix the comments before pushing/Regards Hans


On 10/10/2017 11:04 AM, Anders Widell wrote:
Ack with minor comments inline, marked AndersW>

regards,
Anders Widell

On 10/06/2017 11:10 AM, Hans Nordeback wrote:
---
  scripts/opensaf_scale_out  | 14 +++++++++-
  src/clm/README             | 17 ++++++++----
  src/clm/clmd/clms_cb.h     |  2 ++
  src/clm/clmd/clms_evt.c    | 32 ++++++++++++++++++-----
  src/clm/clmd/clms_mds.c    | 21 +++++++++++++++
  src/clm/clmnd/cb.h         |  2 ++
  src/clm/clmnd/clmna.conf   |  4 +++
  src/clm/clmnd/main.c       | 64 ++++++++++++++++++++++++++++++++++++++++++++--
  src/clm/common/clmsv_msg.h |  2 ++
  9 files changed, 143 insertions(+), 15 deletions(-)

diff --git a/scripts/opensaf_scale_out b/scripts/opensaf_scale_out
index 6fdcba75e..51ebcff74 100644
--- a/scripts/opensaf_scale_out
+++ b/scripts/opensaf_scale_out
@@ -35,6 +35,18 @@ export LD_LIBRARY_PATH=$libdir:$LD_LIBRARY_PATH
  # Remove the following line when customizing this script.
  exit 0
  +# Env variable CLM_IFS contains field separator for the
+# input argument, example on usage:
+# if [ -n "$CLM_IFS" ]; then
+#    IFS=$CLM_IFS
+#    logger "Using ifs [$IFS]"
+# fi
+#
+# for arg in $@

AndersW> The example code above doesn't work when there are spaces in clm_user_data (it performs word splitting). Add double quotes around $@

+# do
+#    logger "> [$arg]"
+# done
+
  tmpdir=$(mktemp -d -t opensaf_scale_out.XXXXXXXXXX)
  destructor() {
    rm -rf "$tmpdir"
@@ -47,7 +59,7 @@ imm_xml=$tmpdir/imm.xml
    immfind -c SaClmNode | sed -e 's/^[^=]*=//;s/,.*$//' > "$nodes_cfg_tmp"
  for node in "$@"; do
-    node_name=$(echo "$node" | cut -d, -f2)
+    node_name=$(echo "$node" | cut -d$CLM_IFS -f2)

AndersW> Shellcheck complains about the line above, suggesting that you should add double qoutes around $CLM_IFS.

      echo "$node_name" >> "$nodes_cfg_tmp"
  done
  rm -f "$nodes_cfg"
diff --git a/src/clm/README b/src/clm/README
index dee3e64f2..50e683ca5 100644
--- a/src/clm/README
+++ b/src/clm/README
@@ -64,11 +64,18 @@ the script will check if the new node is eligible to be added to the cluster,   and if so add the necessary IMM objects so that the node will be able to join   the next time it tries. The script will be called with one or more command-line   arguments, where each argument is a comma-separated list of properties of a node -that wishes to join the cluster. Currently, the comma-separated list in each -command-line argument contains only two entries, but the script should be -forwards compatible with future extensions where more entries may be added to -the comma-separated list. The first entry in the list is the node id represented -as a decimal number. The second entry in the list is the name of the node.
+that wishes to join the cluster. The comma separator can be changed by
+setting variable CLMNA_IFS in clmna.conf to use another field separator, the
+field separator is passed in environment variable CLM_IFS to the
+opensaf_scale_out script.
+Currently, the comma-separated list in each command-line argument contains
+four entries, node-id, node-name, node-ipaddress, user-data.
+But the script should be forwards compatible with future extensions where more +entries may be added to the comma-separated list. The first entry in the list +is the node id represented as a decimal number. The second entry in the list is +the name of the node. The third entry is the IP address of the node. The fourth
+entry is optional user data that can be entered in a file named
+/etc/opensaf/clm_user_data, up to 256 characters can be given.
    NOTE: the script must be idempotent, i.e. it must be harmless to call it more   than one time with the same parameters. The second call should do nothing since
diff --git a/src/clm/clmd/clms_cb.h b/src/clm/clmd/clms_cb.h
index 1bcc451cf..e381f8f2f 100644
--- a/src/clm/clmd/clms_cb.h
+++ b/src/clm/clmd/clms_cb.h
@@ -254,6 +254,8 @@ typedef struct clms_cb_t {
    bool is_scale_out_thread_running;
    /* Full path to the scale-out script, or NULL if feature is disabled */
    char *scale_out_script;
+  /* internal field separator */
+  char ifs;
  } CLMS_CB;
    typedef struct clms_lock_tmr_t { SaNameT node_name; } CLMS_LOCK_TMR;
diff --git a/src/clm/clmd/clms_evt.c b/src/clm/clmd/clms_evt.c
index 84e7b3c6d..8352af869 100644
--- a/src/clm/clmd/clms_evt.c
+++ b/src/clm/clmd/clms_evt.c
@@ -44,7 +44,7 @@ static uint32_t proc_rda_evt(CLMSV_CLMS_EVT *evt);
  static uint32_t proc_mds_quiesced_ack_msg(CLMSV_CLMS_EVT *evt);
  static uint32_t proc_node_lock_tmr_exp_msg(CLMSV_CLMS_EVT *evt);
  static uint32_t proc_node_up_msg(CLMS_CB *cb, CLMSV_CLMS_EVT *evt);
-static void execute_scale_out_script(int argc, char *argv[]);
+static void execute_scale_out_script(int argc, char *argv[], char clm_ifs);
  static void *scale_out_thread(void *arg);
  static void start_scale_out_thread(CLMS_CB *cb);
  static void scale_out_node(CLMS_CB *cb,
@@ -300,15 +300,17 @@ done:
   * and the second string is the node name. This function blocks until the script
   * has exited.
   */
-static void execute_scale_out_script(int argc, char *argv[])
+static void execute_scale_out_script(int argc, char *argv[], char clm_ifs)
  {
      struct rlimit rlim;
      int nofile = 1024;
-    char *const env[] = {scale_out_path_env, NULL};
+    char *env[3];
+    char ifs[10];
        TRACE_ENTER();
      osafassert(argc >= 1 && argv[argc] == NULL);
-    LOG_NO("Running script %s to scale out %d node(s)", argv[0], argc - 1);
+    LOG_NO("Running script %s to scale out %d node(s), clm_ifs: [%c] ",
+        argv[0], argc - 1, clm_ifs);
        if (getrlimit(RLIMIT_NOFILE, &rlim) == 0) {
          if (rlim.rlim_cur != RLIM_INFINITY &&
@@ -326,6 +328,10 @@ static void execute_scale_out_script(int argc, char *argv[])
      if (child_pid == 0) {
          for (int fd = 3; fd < nofile; ++fd)
              close(fd);
+        snprintf(ifs,  sizeof(ifs), "CLM_IFS=%c", clm_ifs);
+        env[0] = scale_out_path_env;
+        env[1] = ifs;
+        env[2] = NULL;
          execve(argv[0], argv, env);
          _Exit(123);
      } else if (child_pid != (pid_t)-1) {
@@ -396,7 +402,8 @@ static void *scale_out_thread(void *arg)
osaf_mutex_unlock_ordie(&cb->scale_out_data_mutex);
          if (no_of_pending_nodes == 0)
              break;
-        execute_scale_out_script(no_of_pending_nodes + 1, argv);
+        execute_scale_out_script(no_of_pending_nodes + 1, argv,
+            cb->ifs);
          for (size_t i = 0; i != no_of_pending_nodes; ++i) {
              free(argv[i + 1]);
          }
@@ -453,6 +460,8 @@ static void scale_out_node(CLMS_CB *cb,
                 const clmsv_clms_node_up_info_t *nodeup_info)
  {
      char node_name[SA_MAX_NAME_LENGTH];
+    char user_data[SA_MAX_NAME_LENGTH];
+    char ifs; // Internal Field Separator
        TRACE_ENTER();
      size_t name_len = nodeup_info->node_name.length < SA_MAX_NAME_LENGTH
@@ -461,6 +470,14 @@ static void scale_out_node(CLMS_CB *cb,
      memcpy(node_name, nodeup_info->node_name.value, name_len);
      node_name[name_len] = '\0';
  +    size_t user_data_len = nodeup_info->user_data.length < SA_MAX_NAME_LENGTH
+                  ? nodeup_info->user_data.length
+                  : (SA_MAX_NAME_LENGTH - 1);
+    memcpy(user_data, nodeup_info->user_data.value, user_data_len);
+    user_data[user_data_len] = '\0';
+
+    ifs = cb->ifs = nodeup_info->ifs;
+
      osaf_mutex_lock_ordie(&cb->scale_out_data_mutex);
      size_t no_of_pending_nodes = cb->no_of_pending_nodes;
      size_t no_of_inprogress_nodes = cb->no_of_inprogress_nodes;
@@ -497,8 +514,9 @@ static void scale_out_node(CLMS_CB *cb,
          memcpy(node_address, nodeup_info->address.value, addr_len);
          node_address[addr_len] = '\0';
          char *strp;
-        if (asprintf(&strp, "%" PRIu32 ",%s,%s,", nodeup_info->node_id,
-                 node_name, node_address) != -1) {
+        if (asprintf(&strp, "%" PRIu32 "%c%s%c%s%c%s%c",
+            nodeup_info->node_id, ifs, node_name,
+            ifs, node_address, ifs, user_data, ifs) != -1) {
              LOG_NO("Queuing request to scale out node 0x%" PRIx32
                     " (%s)",
                     nodeup_info->node_id, node_name);
diff --git a/src/clm/clmd/clms_mds.c b/src/clm/clmd/clms_mds.c
index 1eb0e1e62..ab647f30a 100644
--- a/src/clm/clmd/clms_mds.c
+++ b/src/clm/clmd/clms_mds.c
@@ -787,6 +787,27 @@ static uint32_t clms_dec_nodeup_msg(NCS_UBAID *uba, CLMSV_MSG *msg)
      TRACE("nodename %s length %d",
msg->info.api_info.param.nodeup_info.node_name.value,
msg->info.api_info.param.nodeup_info.node_name.length);
+
+ memset(&msg->info.api_info.param.nodeup_info.user_data, 0, sizeof(SaNameT));
+    p8 = ncs_dec_flatten_space(uba, local_data, 2);
+    if (p8 != NULL) {
+        total_bytes += clmsv_decodeSaNameT(
+            uba, &(msg->info.api_info.param.nodeup_info.user_data));
+        TRACE("userdata %s length %d",
+ msg->info.api_info.param.nodeup_info.user_data.value,
+ msg->info.api_info.param.nodeup_info.user_data.length);
+    }
+
+    p8 = ncs_dec_flatten_space(uba, local_data, 1);
+    uint8_t ifs = 0;
+    if (p8 != NULL) {
+        ifs = ncs_decode_8bit(&p8);
+        ncs_dec_skip_space(uba, 1);
+        total_bytes += 1;
+        TRACE("CLM_IFS : [%c] ", ifs);
+    }
+    msg->info.api_info.param.nodeup_info.ifs = ifs;
+
      p8 = ncs_dec_flatten_space(uba, local_data, 8);
      // Old protocol versions don't have the boot_time field. Use the current
      // wall clock time if boot_time isn't present in the message.
diff --git a/src/clm/clmnd/cb.h b/src/clm/clmnd/cb.h
index 9b26a9bf5..2973e152f 100644
--- a/src/clm/clmnd/cb.h
+++ b/src/clm/clmnd/cb.h
@@ -37,6 +37,8 @@
  typedef struct node_detail_t {
    SaUint32T node_id;
    SaNameT node_name;
+  SaNameT user_data;
+  SaInt8T ifs;
    SaTimeT boot_time;
    SaUint16T no_of_addresses;
    SaClmNodeAddressT address;
diff --git a/src/clm/clmnd/clmna.conf b/src/clm/clmnd/clmna.conf
index 18a5a1b5a..ed4b1a754 100644
--- a/src/clm/clmnd/clmna.conf
+++ b/src/clm/clmnd/clmna.conf
@@ -31,5 +31,9 @@ export CLMNA_ENV_HEALTHCHECK_KEY="Default"
  #export CLMNA_ADDR_FAMILY=1
  #export CLMNA_ADDR_VALUE=10.130.100.114
  +# The string argument passed to the opensaf_scale_out script is default +# comma separated. To use another separator character uncomment the next line.
+#export CLMNA_IFS=";"
+
  # Uncomment the next line to enable info level logging
  #args="--loglevel=info"
diff --git a/src/clm/clmnd/main.c b/src/clm/clmnd/main.c
index 3a8479600..183570258 100644
--- a/src/clm/clmnd/main.c
+++ b/src/clm/clmnd/main.c
@@ -15,7 +15,7 @@
   *             Ericsson AB
   *
   */
-
+#include <stdio.h>
  #include <errno.h>
  #include <inttypes.h>
  #include <saClm.h>
@@ -389,6 +389,20 @@ static uint32_t clmna_mds_enc(struct ncsmds_callback_info *info)
              total_bytes += clmsv_encodeSaNameT(
                  uba,
&(msg->info.api_info.param.nodeup_info.node_name));
+
+            total_bytes += clmsv_encodeSaNameT(
+                uba,
+ &(msg->info.api_info.param.nodeup_info.user_data));
+
+            p8 = ncs_enc_reserve_space(uba, 1);
+            ncs_encode_8bit(
+                &p8,
+                msg->info.api_info.param.nodeup_info.ifs);
+            ncs_enc_claim_space(uba, 1);
+            total_bytes += 1;
+            TRACE("Encoded CLM_IFS: [%c] ",
+                  msg->info.api_info.param.nodeup_info.ifs);
+
              p8 = ncs_enc_reserve_space(uba, 8);
              ncs_encode_64bit(
                  &p8,
@@ -508,9 +522,46 @@ static uint32_t clmna_mds_init(void)
      return rc;
  }
  +static void get_user_data(NODE_INFO *node)
+{
+    FILE *fp;
+
+    fp = fopen(PKGSYSCONFDIR "/clm_user_data", "r");
+    if (fp == NULL) {
+        LOG_IN("Could not open file %s - %s", PKGSYSCONFDIR "/clm_user_data",
+               strerror(errno));
+        return;
+    }
+
+    if (fgets((char*) node->user_data.value, sizeof(node->user_data.value),
+        fp) != NULL) {
+        node->user_data.length = strnlen((char *)node->user_data.value,
+            sizeof(node->user_data.value));
+    } else {
+        LOG_WA("Could not read file %s", PKGSYSCONFDIR "/clm_user_data");
+    }
+
+    if (memchr(node->user_data.value, node->ifs, node->user_data.length) != NULL) { +        LOG_WA("CLM IFS [%c] was found in %s", node->ifs, node->user_data.value);
+        memset(&node->user_data, 0, sizeof(SaNameT));
+    }
+
+    fclose(fp);
+
+}
+
  static int get_node_info(NODE_INFO *node)
  {
      FILE *fp;
+    const char *ifs;
+
+    if ((ifs = getenv("CLMNA_IFS")) == NULL) {
+        node->ifs = ',';  // default field separator
+    } else {
+        node->ifs = *ifs;
+    }
+
+    get_user_data(node);
        fp = fopen(PKGSYSCONFDIR "/node_name", "r");
      if (fp == NULL) {
@@ -528,6 +579,11 @@ static int get_node_info(NODE_INFO *node)
      node->node_name.length = strlen((char *)node->node_name.value);
      TRACE("node name: '%s'", node->node_name.value);
  +    if (memchr(node->node_name.value, node->ifs, node->node_name.length) != NULL) { +        LOG_ER("CLM IFS [%c] was found in %s", node->ifs, node->node_name.value);
+        return -1;
+    }
+
      fp = fopen(PKGLOCALSTATEDIR "/node_id", "r");
      if (fp == NULL) {
          LOG_ER("Could not open file %s - %s",
@@ -561,7 +617,8 @@ static int get_node_info(NODE_INFO *node)
          if (errno != 0 || *endptr != '\0' || *family == '\0')
              family = NULL;
      }
-    if (family != NULL && value != NULL) {
+    if (family != NULL && value != NULL &&
+        memchr(value, node->ifs, strlen(value)) == NULL) {
          size_t len = strlen(value);
          if (len > SA_CLM_MAX_ADDRESS_LENGTH)
              len = SA_CLM_MAX_ADDRESS_LENGTH;
@@ -678,6 +735,9 @@ static void clmna_process_dummyup_msg(void)
          msg.info.api_info.param.nodeup_info.no_of_addresses =
              self_node.no_of_addresses;
          msg.info.api_info.param.nodeup_info.address = self_node.address; +        msg.info.api_info.param.nodeup_info.user_data = self_node.user_data;
+        msg.info.api_info.param.nodeup_info.ifs = self_node.ifs;
+
          stop_scale_out_retry_tmr();
          start_scale_out_retry_tmr(CLMNA_JOIN_RETRY_TIME);
          uint32_t rc = clmna_mds_msg_send(&msg);
diff --git a/src/clm/common/clmsv_msg.h b/src/clm/common/clmsv_msg.h
index f312659f7..8eb71e836 100644
--- a/src/clm/common/clmsv_msg.h
+++ b/src/clm/common/clmsv_msg.h
@@ -139,6 +139,8 @@ typedef struct clmsv_track_info_t {
  typedef struct {
    SaUint32T node_id;
    SaNameT node_name;
+  SaNameT user_data;
+  SaInt8T ifs;         /* Internal Field Separator */
    SaTimeT boot_time;
    SaUint16T no_of_addresses;
    SaClmNodeAddressT address;



------------------------------------------------------------------------------
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
[email protected]
https://lists.sourceforge.net/lists/listinfo/opensaf-devel

Reply via email to