Beispiel #1
0
void
rwsched_dispatch_set_target_queue(rwsched_tasklet_ptr_t sched_tasklet,
                                  rwsched_dispatch_object_t object,
                                  rwsched_dispatch_queue_t queue)
{
#else
void
rwsched_dispatch_set_target_queue(rwsched_tasklet_ptr_t sched_tasklet,
                                  void *obj,
                                  rwsched_dispatch_queue_t queue)
{
  rwsched_dispatch_object_t object = (rwsched_dispatch_object_t) obj;
#endif
  // Validate input paraemters
  RW_CF_TYPE_VALIDATE(sched_tasklet, rwsched_tasklet_ptr_t);
  rwsched_instance_ptr_t instance = sched_tasklet->instance;
  RW_CF_TYPE_VALIDATE(instance, rwsched_instance_ptr_t);
  RW_ASSERT_TYPE(queue, rwsched_dispatch_queue_t);

  // If libdispatch is enabled for the entire instance, then call the libdispatch routine
  if (instance->use_libdispatch_only) {
    dispatch_set_target_queue(object._object->header.libdispatch_object._do,
			      queue->header.libdispatch_object._dq);
    return;
  }

  // Not yet implemented
  RW_CRASH();
}
Beispiel #2
0
rw_status_t rwmain_bootstrap(struct rwmain_gi * rwmain)
{
  rw_status_t status;

  // If this instance has no parent then there is nothing in the zookeeper
  // yet.  We need to make a node so that anything started during bootstrap
  // can correctly link itself as a child.
  if (!rwmain->parent_id) {
    status = update_zk(rwmain);
    RW_ASSERT(status == RW_STATUS_SUCCESS);
  }

  if (rwmain->component_type == RWVCS_TYPES_COMPONENT_TYPE_RWPROC)
    status = bootstrap_rwproc(rwmain);
  else if (rwmain->component_type == RWVCS_TYPES_COMPONENT_TYPE_RWVM)
    status = bootstrap_rwvm(rwmain);
  else {
    status = RW_STATUS_NOTFOUND;
    RW_CRASH();
    goto done;
  }

done:
  return status;
}
Beispiel #3
0
rwsched_dispatch_queue_t
rwsched_dispatch_queue_create(rwsched_tasklet_ptr_t sched_tasklet,
                              const char *label,
                              dispatch_queue_attr_t attr)
{
  struct rwsched_dispatch_queue_s *queue;

  // Validate input paraemters
  RW_CF_TYPE_VALIDATE(sched_tasklet, rwsched_tasklet_ptr_t);
  rwsched_instance_ptr_t instance = sched_tasklet->instance;
  RW_CF_TYPE_VALIDATE(instance, rwsched_instance_ptr_t);

  // Allocate memory for the dispatch queue
  queue = (rwsched_dispatch_queue_t) RW_MALLOC0_TYPE(sizeof(*queue), rwsched_dispatch_queue_t);
  RW_ASSERT_TYPE(queue, rwsched_dispatch_queue_t);

  // If libdispatch is enabled for the entire instance, then call the libdispatch routine
  if (instance->use_libdispatch_only) {
    queue->header.libdispatch_object._dq = dispatch_queue_create(label, attr);
    RW_ASSERT(queue->header.libdispatch_object._dq);

    rwsched_tasklet_ref(sched_tasklet);
    ck_pr_inc_32(&sched_tasklet->counters.queues);

    return queue;
  }

  // Not yet implemented
  RW_CRASH();
  return NULL;
}
Beispiel #4
0
rw_status_t process_init_phase(struct rwmain_gi * rwmain)
{
  rw_status_t status;
  rwvcs_instance_ptr_t rwvcs;

  rwvcs = rwmain->rwvx->rwvcs;

  if (rwvcs->pb_rwmanifest->init_phase->settings->rwvcs->no_autostart == false) {
    vcs_manifest_component *m_component;
    char * instance_name = NULL;

    instance_name = to_instance_name(rwmain->component_name, rwmain->instance_id);
    RW_ASSERT(*instance_name);

    // Lookup the component to start
    status = rwvcs_manifest_component_lookup(rwvcs, rwmain->component_name, &m_component);
    rwmain_trace_info(rwmain, "rwvcs_manifest_component_lookup %s", rwmain->component_name);
    RW_ASSERT(status == RW_STATUS_SUCCESS);

    if (m_component->component_type == RWVCS_TYPES_COMPONENT_TYPE_RWVM) {
      RWVCS_LATENCY_CHK_PRE(rwmain->rwvx->rwsched);
      rwmain_rwvm_init(
          rwmain,
          m_component->rwvm,
          rwmain->component_name,
          rwmain->instance_id,
          instance_name,
          rwmain->parent_id);
      RWVCS_LATENCY_CHK_POST(rwmain->rwvx->rwtrace, RWTRACE_CATEGORY_RWMAIN,
                             rwmain_rwvm_init, "rwmain_rwvm_init:%s", instance_name);
    } else if (m_component->component_type == RWVCS_TYPES_COMPONENT_TYPE_RWPROC) {
      RWVCS_LATENCY_CHK_PRE(rwmain->rwvx->rwsched);
      rwmain_rwproc_init(
          rwmain,
          m_component->rwproc,
          rwmain->component_name,
          rwmain->instance_id,
          instance_name,
          rwmain->parent_id);
      RWVCS_LATENCY_CHK_POST(rwmain->rwvx->rwtrace, RWTRACE_CATEGORY_RWMAIN,
                             rwmain_rwproc_init, "rwmain_rwproc_init:%s", instance_name);
    } else {
      rwmain_trace_crit(
          rwmain,
          "rwmain cannot start a component which is not a vm or process (%s)",
          m_component->component_name);
      RW_CRASH();
    }
  }

  return RW_STATUS_SUCCESS;
}
Beispiel #5
0
int
rwmsg_toytask_block(rwmsg_toytask_t *toy, uint64_t id, int timeout_ms)
{
  rwsched_instance_ptr_t instance;
  rwmsg_toytask_t *toytask = toy;
  CFSocketContext cf_context = { 0, NULL, NULL, NULL, NULL };
  rwsched_CFSocketRef cfsocket;
  struct rwmsg_toyfd_s *toyfd;

  // Validate input parameters
  RW_CF_TYPE_VALIDATE(toytask, rwtoytask_tasklet_ptr_t);

  // Get the rwsched instance from the toytask
  instance = toytask->toysched->rwsched_instance;
  RW_CF_TYPE_VALIDATE(instance, rwsched_instance_ptr_t);

  // Lookup the cfsocket corresponding to id
  RW_ASSERT(id < toytask->rwsched_tasklet_info->cfsocket_array->len);
  cfsocket = g_array_index(toytask->rwsched_tasklet_info->cfsocket_array, rwsched_CFSocketRef, id);
  RW_ASSERT(cfsocket->index == id);
  rwsched_tasklet_CFSocketGetContext(toytask->rwsched_tasklet_info, cfsocket, &cf_context);
  toyfd = cf_context.info;

  rwsched_CFRunLoopSourceRef wakeup_source;
  double secondsToWait = timeout_ms * .001;
  wakeup_source = rwsched_tasklet_CFRunLoopRunTaskletBlock(toytask->rwsched_tasklet_info,
						   cfsocket->callback_context.cfsource,
						   secondsToWait);

  // Set the return value based on which dispatch source woke up on the semaphore
  int revents = 0;
  if (wakeup_source == NULL) {
    revents = 0;
  }
  else if (wakeup_source == toyfd->read_context.source.source) {
    revents = POLLIN;
  }
  else if (wakeup_source == toyfd->write_context.source.source) {
    revents = POLLOUT;
  }
  else {
    // This should never happen as one of the sources should have signaled the semahpore to wake it up
    RW_CRASH();
  }

  // Return the revents value to the caller
  return revents;
}
Beispiel #6
0
static rw_component_type component_type_str_to_enum(const char * type)
{
  if (!strcmp(type, "rwcollection"))
    return RWVCS_TYPES_COMPONENT_TYPE_RWCOLLECTION;
  else if (!strcmp(type, "rwvm"))
    return RWVCS_TYPES_COMPONENT_TYPE_RWVM;
  else if (!strcmp(type, "rwproc"))
    return RWVCS_TYPES_COMPONENT_TYPE_RWPROC;
  else if (!strcmp(type, "proc"))
    return RWVCS_TYPES_COMPONENT_TYPE_PROC;
  else if (!strcmp(type, "rwtasklet"))
    return RWVCS_TYPES_COMPONENT_TYPE_RWTASKLET;
  else {
    RW_CRASH();
    return RWVCS_TYPES_COMPONENT_TYPE_RWCOLLECTION;
  }
}
Beispiel #7
0
void
rwsched_dispatch_after_f(rwsched_tasklet_ptr_t sched_tasklet,
                         dispatch_time_t when,
                         rwsched_dispatch_queue_t queue,
                         void *context,
                         dispatch_function_t handler)
{
  // Validate input paraemters
  RW_CF_TYPE_VALIDATE(sched_tasklet, rwsched_tasklet_ptr_t);
  rwsched_instance_ptr_t instance = sched_tasklet->instance;
  RW_CF_TYPE_VALIDATE(instance, rwsched_instance_ptr_t);
  RW_ASSERT_TYPE(queue, rwsched_dispatch_queue_t);

  // If libdispatch is enabled for the entire instance, then call the libdispatch routine
  if (instance->use_libdispatch_only) {
    RW_ASSERT(queue->header.libdispatch_object._dq);
    if (queue == instance->main_rwqueue &&
        sched_tasklet->blocking_mode.blocked) {
      //RW_CRASH();
      rwsched_dispatch_what_ptr_t what = (rwsched_dispatch_what_ptr_t) RW_MALLOC0_TYPE(sizeof(*what), rwsched_dispatch_what_ptr_t); /* always leaked! */
      what->type = RWSCHED_DISPATCH_ASYNC;
      what->closure.handler = handler;
      what->closure.context = context;
      what->queue = queue;
      g_array_append_val(sched_tasklet->dispatch_what_array, what);
    }
    else {
      rwsched_dispatch_what_ptr_t what = (rwsched_dispatch_what_ptr_t) RW_MALLOC0_TYPE(sizeof(*what), rwsched_dispatch_what_ptr_t);
      what->type = RWSCHED_DISPATCH_ASYNC;
      what->closure.handler = handler;
      what->closure.context = context;
      what->queue = queue;
      rwsched_tasklet_ref(sched_tasklet);
      what->tasklet_info = sched_tasklet;
      dispatch_after_f(when, queue->header.libdispatch_object._dq, (void*)what, rwsched_dispatch_intercept);
    }
    return;
  }

  // Not yet implemented
  RW_CRASH();
}
Beispiel #8
0
static void
rwmsg_toysched_io_callback(rwsched_CFSocketRef s,
			   CFSocketCallBackType type,
			   CFDataRef address,
			   const void *data,
			   void *info)
{
  UNUSED(address); UNUSED(data);
  rwsched_instance_ptr_t instance;
  struct rwmsg_toyfd_s *toyfd;
  rwmsg_toytask_t *toytask;
  //static int index = 1;
  int revents = 0;

  // Validate input parameters
  toyfd = (struct rwmsg_toyfd_s *) info;
  RW_CF_TYPE_VALIDATE(toyfd, rwmsg_toyfd_ptr_t);
  toytask = toyfd->toytask;
  RW_CF_TYPE_VALIDATE(toytask, rwtoytask_tasklet_ptr_t);

  // Get the rwsched instance from the toytask
  instance = toytask->toysched->rwsched_instance;
  RW_CF_TYPE_VALIDATE(instance, rwsched_instance_ptr_t);

  // Determine whether this callback represents a read or write toyfd event
  if (type == kCFSocketReadCallBack) {
    revents = POLLIN;
  }
  else if (type == kCFSocketWriteCallBack) {
    revents = POLLOUT;
  }
  else {
    RW_CRASH();
  }

  // Invoke the user specified callback
  RW_ASSERT(toyfd->cb);
  toyfd->cb(toyfd->id, toyfd->fd, revents, toyfd->ud);

  // Inalidate the socket so the callback is not invoked again
  rwsched_tasklet_CFSocketInvalidate(toytask->rwsched_tasklet_info, s);
}
Beispiel #9
0
rwsched_dispatch_queue_t
rwsched_dispatch_get_global_queue(rwsched_tasklet_ptr_t sched_tasklet,
				  long priority) {
  // Validate input paraemters
  RW_CF_TYPE_VALIDATE(sched_tasklet, rwsched_tasklet_ptr_t);
  rwsched_instance_ptr_t instance = sched_tasklet->instance;
  RW_CF_TYPE_VALIDATE(instance, rwsched_instance_ptr_t);

  RW_ASSERT(priority >= DISPATCH_QUEUE_PRIORITY_BACKGROUND);
  RW_ASSERT(priority <= DISPATCH_QUEUE_PRIORITY_HIGH);
  int i=0;
  for (i=0; i<RWSCHED_DISPATCH_QUEUE_GLOBAL_CT; i++) {
    if (instance->global_rwqueue[i].pri == priority) {
      RW_ASSERT_TYPE(instance->global_rwqueue[i].rwq, rwsched_dispatch_queue_t);
      return instance->global_rwqueue[i].rwq;
    }
  }
  RW_CRASH();
  return NULL;
}
Beispiel #10
0
void
rwsched_dispatch_sync_f(rwsched_tasklet_ptr_t sched_tasklet,
                        rwsched_dispatch_queue_t queue,
                        void *context,
                        dispatch_function_t handler)
{
  // Validate input paraemters
  RW_CF_TYPE_VALIDATE(sched_tasklet, rwsched_tasklet_ptr_t);
  rwsched_instance_ptr_t instance = sched_tasklet->instance;
  RW_CF_TYPE_VALIDATE(instance, rwsched_instance_ptr_t);
  RW_ASSERT_TYPE(queue, rwsched_dispatch_queue_t);

  // If libdispatch is enabled for the entire instance, then call the libdispatch routine
  if (instance->use_libdispatch_only) {
    dispatch_sync_f(queue->header.libdispatch_object._dq, context, handler);
    return;
  }

  // Not yet implemented
  RW_CRASH();
}
Beispiel #11
0
rw_status_t
read_pacemaker_state(rwmain_pm_struct_t *pm)
{
  char buffer[BUF_LEN];
  char tmp[999];
  bool file_read = false;
  RW_ASSERT(pm);

  // Read the pacemaker status
  sprintf(tmp,
          "sudo --non-interactive cat %s",
          PACEMAKER_CRM_MON_FULL_FNAME);
  FILE *fp = popen(tmp, "r");
  buffer[0] = 0;
  while (fgets(tmp, sizeof(tmp), fp) != NULL ) {
    strcat(buffer, tmp);
    file_read = true;
  }
  fclose(fp);

  #define FIND_VALUE(b_ptr, pat_str, s_char, e_char) \
  ({ \
    char *p1, *p2; \
    if (pat_str[0]!='\0') {  \
      p1 = strstr(b_ptr, pat_str); if (!p1) goto _done; \
      p1 += strlen(pat_str); \
    } else {  \
      p1 = b_ptr;  \
    } \
    p1 = strchr(p1, s_char); if (!p1) goto _done;  \
    p1++; \
    p2 = strchr(p1, e_char); if (!p2) goto _done;  \
    p2[0] = '\0';  \
    p2++; \
    b_ptr = p2; \
    &(p1[0]); \
  })

  if (file_read) {
    memset(pm, '\0', sizeof(*pm));
    char *buf_ptr;
    struct in_addr addr;
    buf_ptr = &(buffer[0]);
    char *dc_name = FIND_VALUE(buf_ptr, "Current DC", ' ', ' ');
    char my_hostname[999];
    int r = gethostname(my_hostname, sizeof(my_hostname));
    RW_ASSERT(r != -1);
    if (!strcmp(my_hostname, dc_name)) {
      pm->i_am_dc = true;
    }
    char *dc_ip = FIND_VALUE(buf_ptr, "", '(', ')');
    addr.s_addr = htonl(atoi(dc_ip));
    fprintf(stderr, "My Host Name: *%s* Current DC : *%s* %s\n", my_hostname, dc_name, inet_ntoa(addr));
    int i = 0;
    while (1) {
      char *node_ip = FIND_VALUE(buf_ptr, "Node:", '(', ')');
      addr.s_addr = htonl(atoi(node_ip));

      char *state = FIND_VALUE(buf_ptr, "", '>', '<');

      pm->ip_entry[i].pm_ip_addr = strdup(inet_ntoa(addr));
      if (!strcmp(state,"OFFLINE")) {
          pm->ip_entry[i].pm_ip_state = RWMAIN_PM_IP_STATE_FAILED;
      } else if (!strcmp(state, "online")) {
        if (!strcmp(dc_ip, node_ip)) {
          pm->ip_entry[i].pm_ip_state = RWMAIN_PM_IP_STATE_LEADER;
        } else {
          pm->ip_entry[i].pm_ip_state = RWMAIN_PM_IP_STATE_ACTIVE;
        }
      } else {
        fprintf(stderr, "pacemaker: Node=%s State=%s\n", node_ip, state);
        RW_CRASH();
      }
      i++;
    }
  } else {
    return RW_STATUS_FAILURE;
  }
_done:
  return RW_STATUS_SUCCESS;
}
Beispiel #12
0
void start_pacemaker_and_determine_role(
    rwvx_instance_ptr_t rwvx,
    vcs_manifest       *pb_rwmanifest,
    rwmain_pm_struct_t *pm)
{
  RW_ASSERT(rwvx);
  RW_ASSERT(pb_rwmanifest);
  RW_ASSERT(pm);

  if (pb_rwmanifest->bootstrap_phase->n_ip_addrs_list == 1) {
    pm->i_am_dc = true;
    return;
  }

  #define COROSYNC_CONF_WO_NODES \
    "totem {\n" \
      "\tversion: 2\n" \
      "\tcrypto_cipher: none\n" \
      "\tcrypto_hash: none\n" \
      "\tinterface {\n" \
        "\t\t ringnumber: 0\n" \
        "\t\t bindnetaddr: %s\n" \
        "\t\t mcastport: 5405\n" \
        "\t\t ttl: 1\n\t}\n" \
      "\ttransport: udpu\n}\n" \
    "quorum {\n\tprovider: corosync_votequorum\n}\n" \
    "nodelist {\n"

  #define COROSYNC_CONF_NODE_TEMPLATE \
      "\tnode {\n\t\tring0_addr: %s\n\t}\n"

      //"\tnode {\n\t\tring0_addr: %s\n\t\tnodeid: %u\n\t}\n"

  // Form the corosync_conf to be written to /etc/corosync/corosync.conf
  char corosync_conf[999];
  char *local_mgmt_addr = rwvcs_manifest_get_local_mgmt_addr(pb_rwmanifest->bootstrap_phase);
  RW_ASSERT(local_mgmt_addr);
  sprintf(corosync_conf, COROSYNC_CONF_WO_NODES, local_mgmt_addr);
  if (pb_rwmanifest->bootstrap_phase
      && pb_rwmanifest->bootstrap_phase->ip_addrs_list) {
    RW_ASSERT(pb_rwmanifest->bootstrap_phase->n_ip_addrs_list);
    int i; for (i=0; i<pb_rwmanifest->bootstrap_phase->n_ip_addrs_list; i++) {
      RW_ASSERT(pb_rwmanifest->bootstrap_phase->ip_addrs_list[i]);
      char corosync_conf_node[999];
      sprintf(corosync_conf_node
              ,COROSYNC_CONF_NODE_TEMPLATE
              ,pb_rwmanifest->bootstrap_phase->ip_addrs_list[i]->ip_addr);
              //, i+1);
      strcat(corosync_conf, corosync_conf_node);
    }
  }
  strcat(corosync_conf, "}");
  fprintf(stderr, "Witing to /etc/corosync/corosync.conf\n%s\n", corosync_conf);

  char command[999];
  int r = 0;
  sprintf(command,
          "echo \"%s\" > /tmp/blah;"
          "sudo mv /tmp/blah /etc/corosync/corosync.conf;"
          "sudo chown root /etc/corosync/corosync.conf;"
          "sudo chgrp root /etc/corosync/corosync.conf",
          corosync_conf);
  FILE *fp = popen(command, "r");
  fclose(fp);

#if 0
  pid_t pid;
  char * argv[8];
  int argc = 0;
  pid = fork();
  if (pid < 0) {
    RW_CRASH();
  }
  if (pid == 0) {
    argv[argc++] = "/bin/sudo";
    argv[argc++] = "--non-interactive";
    argv[argc++] = "/usr/sbin/pcs";
    argv[argc++] = "cluster";
    argv[argc++] = "stop";
    argv[argc++] = NULL;
    execv(argv[0], argv);
  }
#else
  fp = popen("sudo pkill crm_mon; sudo pcs cluster stop", "r");
  fclose(fp);
#endif

  usleep(2000000);
  // FIXME: dirty way to stop pacemaker service when rwmain exits
  if ((fork()) == 0) {
    setsid();
    signal(SIGCHLD, SIG_DFL);
    if ((fork()) == 0) {
      sprintf(command,
              "while [ 1 ]; do if ! (ps -A | grep -v %u | grep -q rwmain) 2> /dev/null; then sudo pcs cluster stop; exit; fi; sleep 1; done; sudo pkill crm_mon; sudo rm -f %s 2> /dev/null; rmdir /tmp/corosync/ 2> /dev/null",
              getpid(),
              PACEMAKER_CRM_MON_FULL_FNAME);
      fp = popen(command, "r");
      fclose(fp);
      exit(0);
    } else {
      exit(0);
    }
  }

#if 0
  pid = fork();
  if (pid < 0) {
    RW_CRASH();
  }
  if (pid == 0) {
    argv[argc++] = "/bin/sudo";
    argv[argc++] = "--non-interactive";
    argv[argc++] = "/usr/sbin/pcs";
    argv[argc++] = "cluster";
    argv[argc++] = "start";
    argv[argc++] = NULL;
    execv(argv[0], argv);
  }
#else
  fp = popen("sudo pcs cluster start", "r");
  fclose(fp);
#endif
  char *pacemaker_dc_found = NULL;
  while (1) {
    usleep(2000000);
    FILE *fp;
    fp = popen("sudo pcs status xml", "r");
    char buff[999];
    while (fgets(buff, sizeof(buff), fp) != NULL ) {
      //fprintf(stderr,"%s", buff);
      if ((pacemaker_dc_found = strstr(buff, "current_dc present=\"true\""))) {
        break;
      }
    }
    fclose(fp);
    if (pacemaker_dc_found) {
      char my_hostname[999];
      char *pacemaker_dc_name = NULL;
      char *pacemaker_dc_name_end = NULL;
      r = gethostname(my_hostname, sizeof(my_hostname));
      RW_ASSERT(r != -1);
      pacemaker_dc_name = strstr(pacemaker_dc_found, " name=\"");
      RW_ASSERT(pacemaker_dc_name != NULL);
      pacemaker_dc_name += sizeof(" name=");
      pacemaker_dc_name_end = strstr(pacemaker_dc_name, "\"");
      RW_ASSERT(pacemaker_dc_name_end != NULL);
      pacemaker_dc_name_end[0] = '\0';
      if (!strcmp(my_hostname, pacemaker_dc_name)) {
        fprintf(stderr,"I AM pacemaker DC\n");
      } else {
        fprintf(stderr,"I'm NOT pacemaker DC - my_hostname=%s pacemaker_dc_name=%s\n", my_hostname, pacemaker_dc_name);
      }
      break;
    }
  }

  /*setup a inotify watcher for /tmp/crm_mon.html */
  sprintf(command, "mkdir %s", PACEMAKER_CRM_MON_DIR);
  fp = popen(command, "r");
  fclose(fp);

  sprintf(command, "sudo crm_mon --daemonize --as-html %s", PACEMAKER_CRM_MON_FULL_FNAME);
  fp = popen(command, "r");
  fclose(fp);

  usleep(20000);
  setup_inotify_watcher(rwvx);

  read_pacemaker_state(pm);
}
Beispiel #13
0
/*
 * Initialize the zookeeper with a node for this component.  Used when the
 * component does not have a parent and therefore no one created the zookeeper
 * node yet.
 */
rw_status_t update_zk(struct rwmain_gi * rwmain)
{
  rw_status_t status;
  vcs_manifest_component * mdef;
  rwvcs_instance_ptr_t rwvcs;
  char * id = NULL;
  rw_component_info * ci = NULL;


  rwvcs = rwmain->rwvx->rwvcs;

  RW_ASSERT(!rwmain->parent_id);
  id = to_instance_name(rwmain->component_name, rwmain->instance_id);

  // As we only hit this point when the parent_id is NULL, we are pretty much
  // guaranteed that the definition has to be in the static manifest.
  status = rwvcs_manifest_component_lookup(rwvcs, rwmain->component_name, &mdef);
  if (status != RW_STATUS_SUCCESS) {
    RW_CRASH();
    goto done;
  }


  if (mdef->component_type == RWVCS_TYPES_COMPONENT_TYPE_RWVM) {
    ci = rwvcs_rwvm_alloc(
        rwmain->rwvx->rwvcs,
        rwmain->parent_id,
        rwmain->component_name,
        rwmain->instance_id,
        id);
    if (!ci) {
      RW_CRASH();
      status = RW_STATUS_FAILURE;
      goto done;
    }

    ci->vm_info->vm_ip_address = strdup(rwmain->vm_ip_address);
    ci->vm_info->has_pid = true;
    ci->vm_info->pid = getpid();
    ci->has_state = true;
    ci->state = RW_BASE_STATE_TYPE_STARTING;

    if (mdef->rwvm && mdef->rwvm->has_leader) {
      ci->vm_info->has_leader = true;
      ci->vm_info->leader= mdef->rwvm->leader;
    }
  } else if (mdef->component_type == RWVCS_TYPES_COMPONENT_TYPE_RWPROC) {
    ci = rwvcs_rwproc_alloc(
        rwvcs,
        rwmain->parent_id,
        rwmain->component_name,
        rwmain->instance_id,
        id);
    if (!ci) {
      RW_CRASH();
      status = RW_STATUS_FAILURE;
      goto done;
    }

    ci->proc_info->has_pid = true;
    ci->proc_info->pid = getpid();
    ci->has_state = true;
    ci->proc_info->has_native = true;
    ci->proc_info->native = false;
    ci->state = RW_BASE_STATE_TYPE_STARTING;
  } else {
    RW_CRASH();
    status = RW_STATUS_FAILURE;
    goto done;
  }

  status = rwvcs_rwzk_node_update(rwmain->rwvx->rwvcs, ci);
  if (status != RW_STATUS_SUCCESS) {
    RW_CRASH();
    goto done;
  }


done:
  if (id)
    free(id);

  if (ci)
    protobuf_free(ci);

  return status;
}
Beispiel #14
0
CF_EXPORT rwsched_CFRunLoopSourceRef
rwsched_tasklet_CFRunLoopRunTaskletBlock(rwsched_tasklet_ptr_t sched_tasklet,
        rwsched_CFRunLoopSourceRef blocking_source,
        CFTimeInterval secondsToWait)
{
    // Validate input paraemters
    RW_CF_TYPE_VALIDATE(sched_tasklet, rwsched_tasklet_ptr_t);
    rwsched_instance_ptr_t instance = sched_tasklet->instance;
    RW_CF_TYPE_VALIDATE(instance, rwsched_instance_ptr_t);

    SInt32 runloop_status;
    rwsched_CFRunLoopSourceRef return_source = NULL;
    //int i = 0;

    // Validate input parameters
    RW_CF_TYPE_VALIDATE(instance, rwsched_instance_ptr_t);

    // Make sure this tasklet is not already blocked
    RW_ASSERT(!sched_tasklet->blocking_mode.blocked);

    // Mark the tasklet as blocked
    RW_ZERO_VARIABLE(&sched_tasklet->blocking_mode);
    sched_tasklet->blocking_mode.blocked = TRUE;
    sched_tasklet->blocking_mode.cfsource = blocking_source;

    // Run the run loop in the default mode for up to the block interval specified
    // The run loop will be stopped if an event is avilable for the wakeupSource
    runloop_status = CFRunLoopRunInMode(instance->main_cfrunloop_mode, secondsToWait, false);

    // If the return value is kCFRunLoopRunTimedOut then the run loop timed out
    // If the return value is kCFRunLoopRunStopped then an event occured on the wakeupSource
    // If any other return value occurs, it is considered to be an error
    if (runloop_status == kCFRunLoopRunTimedOut) {
        CFRunLoopRef rl = CFRunLoopGetCurrent();
        return_source = blocking_source;
        if (CFRunLoopContainsSource(rl, blocking_source->cf_object, instance->main_cfrunloop_mode)) {
            return_source = NULL;
        }
    }
    else if (runloop_status == kCFRunLoopRunStopped || runloop_status == kCFRunLoopRunFinished) {
        return_source = blocking_source;
    }
    else {
        RW_CRASH();
    }

    g_rwresource_track_handle = sched_tasklet->rwresource_track_handle;
    g_tasklet_info = sched_tasklet;

    // relocate timers back to the main-mode
    rwsched_cfrunloop_relocate_timers_to_main_mode(sched_tasklet);

    g_rwresource_track_handle = sched_tasklet->rwresource_track_handle;
    g_tasklet_info = sched_tasklet;

    // relocate sources back to the main-mode
    rwsched_cfrunloop_relocate_sources_to_main_mode(sched_tasklet);

    //runloop_status = rwsched_instance_CFRunLoopRunInMode(instance, instance->deferred_cfrunloop_mode, 0.0, false);
    //RW_ASSERT(runloop_status == kCFRunLoopRunFinished || runloop_status == kCFRunLoopRunTimedOut);

    // Mark the tasklet as unblocked
    RW_ZERO_VARIABLE(&sched_tasklet->blocking_mode);

    g_rwresource_track_handle = sched_tasklet->rwresource_track_handle;
    g_tasklet_info = sched_tasklet;

    //Deliver any events on the dispatch sources
    rwsched_dispatch_unblock_sources(sched_tasklet);

    g_rwresource_track_handle = sched_tasklet->rwresource_track_handle;
    g_tasklet_info = sched_tasklet;

    // Return the runloop source that wokeup the blocking call, which is NULL if it timed out
    return return_source;
}
Beispiel #15
0
static rwtasklet_info_ptr_t get_rwmain_tasklet_info(
    rwvx_instance_ptr_t rwvx,
    const char * component_name,
    int instance_id,
    uint32_t vm_instance_id)
{
  rwtasklet_info_ptr_t info;
  char * instance_name = NULL;
  int broker_instance_id;

  info = (rwtasklet_info_ptr_t)RW_MALLOC0(sizeof(struct rwtasklet_info_s));
  if (!info) {
    RW_CRASH();
    goto err;
  }

  instance_name = to_instance_name(component_name, instance_id);
  if (!instance_name) {
    RW_CRASH();
    goto err;
  }

  info->rwsched_instance = rwvx->rwsched;
  info->rwsched_tasklet_info = rwsched_tasklet_new(rwvx->rwsched);
  info->rwtrace_instance = rwvx->rwtrace;
  info->rwvx = rwvx;
  info->rwvcs = rwvx->rwvcs;

  info->identity.rwtasklet_instance_id = instance_id;
  info->identity.rwtasklet_name = strdup(component_name);
  char *rift_var_root = rwtasklet_info_get_rift_var_root(info);
  RW_ASSERT(rift_var_root);

  rw_status_t status = rw_setenv("RIFT_VAR_ROOT", rift_var_root);
  RW_ASSERT(status == RW_STATUS_SUCCESS);
  setenv("RIFT_VAR_ROOT", rift_var_root, true);

  info->rwlog_instance = rwlog_init(instance_name);

  broker_instance_id = 0;
  if (rwvx->rwvcs->pb_rwmanifest->init_phase->settings->rwmsg->multi_broker
      && rwvx->rwvcs->pb_rwmanifest->init_phase->settings->rwmsg->multi_broker->has_enable
      && rwvx->rwvcs->pb_rwmanifest->init_phase->settings->rwmsg->multi_broker->enable) {
    broker_instance_id = vm_instance_id ? vm_instance_id : 1;
  }

  info->rwmsg_endpoint = rwmsg_endpoint_create(
    1,
    instance_id,
    broker_instance_id,
    info->rwsched_instance,
    info->rwsched_tasklet_info,
    info->rwtrace_instance,
    rwvx->rwvcs->pb_rwmanifest->init_phase->settings->rwmsg);

  rwtasklet_info_ref(info);
  free(instance_name);

  return info;

err:
  if (info)
    free(info);

  if (instance_name)
    free(instance_name);

  return NULL;
}
Beispiel #16
0
struct rwmain_gi * rwmain_alloc(
    rwvx_instance_ptr_t rwvx,
    const char * component_name,
    uint32_t instance_id,
    const char * component_type,
    const char * parent_id,
    const char * vm_ip_address,
    uint32_t vm_instance_id)
{
  rw_status_t status;
  int r;
  rwtasklet_info_ptr_t info = NULL;
  rwdts_api_t * dts = NULL;
  struct rwmain_gi * rwmain = NULL;
  char * instance_name = NULL;


  rwmain = (struct rwmain_gi *)malloc(sizeof(struct rwmain_gi));
  if (!rwmain) {
    RW_CRASH();
    goto err;
  }
  bzero(rwmain, sizeof(struct rwmain_gi));

  /* If the component name wasn't specified on the command line, pull it
   * from the manifest init-phase.
   */
  if (!component_name) {
    char cn[1024];

    status = rwvcs_variable_evaluate_str(
        rwvx->rwvcs,
        "$rw_component_name",
        cn,
        sizeof(cn));
    if (status != RW_STATUS_SUCCESS) {
      RW_CRASH();
      goto err;
    }

    rwmain->component_name = strdup(cn);
  } else {
    rwmain->component_name = strdup(component_name);
  }

  if (!rwmain->component_name) {
    RW_CRASH();
    goto err;
  }


  /* If the instance id wasn't specified on the command line pull it from
   * the manifest init-phase if it is there, otherwise autoassign one.
   */
  if (instance_id == 0) {
    int id;

    status = rwvcs_variable_evaluate_int(
        rwvx->rwvcs,
        "$instance_id",
        &id);
    if ((status == RW_STATUS_SUCCESS) && id) {
      rwmain->instance_id = (uint32_t)id;
    } else {
      status = rwvcs_rwzk_next_instance_id(rwvx->rwvcs, &rwmain->instance_id, NULL);
      if (status != RW_STATUS_SUCCESS) {
        RW_CRASH();
        goto err;
      }
    }
  } else {
    rwmain->instance_id = instance_id;
  }

  if (component_type) {
    rwmain->component_type = component_type_str_to_enum(component_type);
  } else {
    char ctype[64];
    status = rwvcs_variable_evaluate_str(
        rwvx->rwvcs,
        "$component_type",
        ctype,
        sizeof(ctype));
    if (status != RW_STATUS_SUCCESS) {
      RW_CRASH();
      goto err;
    }
    rwmain->component_type = component_type_str_to_enum(ctype);
  }

  if (vm_instance_id > 0)
    rwmain->vm_instance_id = vm_instance_id;
  else if (rwmain->component_type == RWVCS_TYPES_COMPONENT_TYPE_RWVM)
    rwmain->vm_instance_id = rwmain->instance_id;
  else {
    int vm_instance_id;
    status = rwvcs_variable_evaluate_int(
        rwvx->rwvcs,
        "$vm_instance_id",
        &vm_instance_id);
    if (status == RW_STATUS_SUCCESS) {
      rwmain->vm_instance_id = (uint32_t)vm_instance_id;
    }
  }
  RW_ASSERT(rwmain->vm_instance_id);


  // 10 hz with tolerance 600
  // TODO: Must take from YANG. These are currently defined as the defaults in rw-base.yang
  rwmain->rwproc_heartbeat = rwproc_heartbeat_alloc(10, 600);
  if (!rwmain->rwproc_heartbeat) {
    RW_CRASH();
    goto err;
  }

  bzero(&rwmain->sys, sizeof(rwmain->sys));

  if (parent_id) {
    rwmain->parent_id = strdup(parent_id);
    if (!rwmain->parent_id) {
      RW_CRASH();
      goto err;
    }
  }
  else {
    char ctype[64];
    status = rwvcs_variable_evaluate_str(
        rwvx->rwvcs,
        "$parent_id",
        ctype,
        sizeof(ctype));
    if (status == RW_STATUS_SUCCESS) {
      rwmain->parent_id = strdup(ctype);
    }
  }


  if (rwvx->rwvcs->pb_rwmanifest->init_phase->settings->rwvcs->collapse_each_rwvm) {
    r = asprintf(&rwmain->vm_ip_address, "127.%u.%u.1", rwmain->instance_id / 256, rwmain->instance_id % 256);
    if (r == -1) {
      RW_CRASH();
      goto err;
    }
  } else if (vm_ip_address) {
    rwmain->vm_ip_address = strdup(vm_ip_address);
    if (!rwmain->vm_ip_address) {
      RW_CRASH();
      goto err;
    }
    char *variable[0];
    r = asprintf(&variable[0], "vm_ip_address = '%s'", vm_ip_address);
    if (r == -1) {
      RW_CRASH();
      goto err;
    }
    status = rwvcs_variable_list_evaluate(
        rwvx->rwvcs,
        1,
        variable);
    if (status != RW_STATUS_SUCCESS) {
      RW_CRASH();
      goto err;
    }
    free(variable[0]);
  } else {
    char buf[32];

    status = rwvcs_variable_evaluate_str(
        rwvx->rwvcs,
        "$vm_ip_address",
        buf,
        sizeof(buf));
    if (status != RW_STATUS_SUCCESS) {
      RW_CRASH();
      goto err;
    }

    rwmain->vm_ip_address = strdup(buf);
    if (!rwmain->vm_ip_address) {
      RW_CRASH();
      goto err;
    }
  }


  rwvx->rwvcs->identity.vm_ip_address = strdup(rwmain->vm_ip_address);
  if (!rwvx->rwvcs->identity.vm_ip_address) {
    RW_CRASH();
    goto err;
  }
  rwvx->rwvcs->identity.rwvm_instance_id = rwmain->vm_instance_id;

  instance_name = to_instance_name(rwmain->component_name, rwmain->instance_id);
  RW_ASSERT(instance_name!=NULL);
  if (rwmain->component_type == RWVCS_TYPES_COMPONENT_TYPE_RWVM) {
    rwvx->rwvcs->identity.rwvm_name = instance_name;
  }
  else if (rwmain->component_type == RWVCS_TYPES_COMPONENT_TYPE_RWPROC) {
    RW_ASSERT(rwmain->parent_id);
    rwvx->rwvcs->identity.rwvm_name = strdup(rwmain->parent_id);
  }

  char rift_var_vm[255];
  if (rwvx->rwvcs->identity.rwvm_name) {
    snprintf(rift_var_vm, 255, "%s%c%s", rwvx->rwvcs->pb_rwmanifest->bootstrap_phase->test_name,
             '-', rwvx->rwvcs->identity.rwvm_name);
  } else {
    snprintf(rift_var_vm, 255, "%s", rwvx->rwvcs->pb_rwmanifest->bootstrap_phase->test_name);
  }

  setenv("RIFT_VAR_VM", rift_var_vm, true);
  info = get_rwmain_tasklet_info(
      rwvx,
      rwmain->component_name,
      rwmain->instance_id,
      rwmain->vm_instance_id);
  if (!info) {
    RW_CRASH();
    goto err;
  }

  if (rwvx->rwsched) {
    if (!rwvx->rwsched->rwlog_instance) {
      rwvx->rwsched->rwlog_instance = rwlog_init("RW.Sched");
    }
  }
  if (!rwvx->rwlog) {
    rwvx->rwlog = rwlog_init("Logging");
  }

  dts = rwdts_api_new(
      info,
      (rw_yang_pb_schema_t *)RWPB_G_SCHEMA_YPBCSD(RwVcs),
      rwmain_dts_handle_state_change,
      NULL,
      NULL);

  if (!dts) {
    RW_CRASH();
    goto err;
  }

  RW_SKLIST_PARAMS_DECL(
      procs_sklist_params,
      struct rwmain_proc,
      instance_name,
      rw_sklist_comp_charptr,
      _sklist);
  RW_SKLIST_INIT(&(rwmain->procs), &procs_sklist_params);

  RW_SKLIST_PARAMS_DECL(
      tasklets_sklist_params,
      struct rwmain_tasklet,
      instance_name,
      rw_sklist_comp_charptr,
      _sklist);
  RW_SKLIST_INIT(&(rwmain->tasklets), &tasklets_sklist_params);

  RW_SKLIST_PARAMS_DECL(
      multivms_sklist_params,
      struct rwmain_multivm,
      key,
      rw_sklist_comp_charbuf,
      _sklist);
  RW_SKLIST_INIT(&(rwmain->multivms), &multivms_sklist_params);


  rwmain->dts = dts;
  rwmain->tasklet_info = info;
  rwmain->rwvx = rwvx;
  r = asprintf(&VCS_GET(rwmain)->vcs_instance_xpath,
               VCS_INSTANCE_XPATH_FMT,
               instance_name);
  if (r == -1) {
    RW_CRASH();
    goto err;
  }
  VCS_GET(rwmain)->instance_name = instance_name;

  goto done;

err:
  if (info) {
    rwsched_tasklet_free(info->rwsched_tasklet_info);
    free(info->identity.rwtasklet_name);
    rwmsg_endpoint_halt(info->rwmsg_endpoint);
    free(info);
  }

  if (dts)
    rwdts_api_deinit(dts);

  if (rwmain->component_name)
    free(rwmain->component_name);

  if (rwmain->parent_id)
    free(rwmain->parent_id);

  if (rwmain)
    free(rwmain);

done:

  return rwmain;
}
Beispiel #17
0
rw_tree_walker_status_t add_xml_child (XMLNode *parent,
                                       rw_confd_value_t *confd,
                                       XMLNode*& child)
{
  confd_cs_node *cs_node = confd->cs_node;
  confd_value_t *child_src = confd->value;
  const char *name = confd_hash2str (confd->cs_node->tag);
  const char *ns = confd_hash2str (confd->cs_node->ns);

  YangNode *child_yn = nullptr;
  child = nullptr;

  YangNode *yn = parent->get_yang_node();
  if (!yn) {
    return RW_TREE_WALKER_FAILURE;
  }

  child_yn = yn->search_child (name, ns);
  if (!child_yn) {
    return RW_TREE_WALKER_FAILURE;
  }

  if (!child_yn->is_leafy()) {
    child = parent->add_child(child_yn);
    if (child) {
      return RW_TREE_WALKER_SUCCESS;
    }

    return RW_TREE_WALKER_FAILURE;
  }

  char value[1024];
  char *val_p = nullptr;
  
  switch (child_src->type) {
    default:
    case C_QNAME: 
    case C_DATETIME: 
    case C_DATE: 
    case C_TIME: 
    case C_DURATION:
    case C_NOEXISTS:
    case C_STR:
    case C_SYMBOL:
    case C_BIT32: 
    case C_BIT64:
    case C_XMLBEGIN:  
    case C_XMLEND: 
    case C_OBJECTREF: 
    case C_UNION: 
    case C_PTR: 
    case C_CDBBEGIN: 
    case C_OID: 
    case C_DEFAULT: 
    case C_IDENTITYREF: 
    case C_XMLBEGINDEL: 
    case C_DQUAD: 
    case C_HEXSTR: 

      RW_CRASH();
    break;
    
    case C_XMLTAG:
      break;

    case C_BUF: 
    case C_INT8: 
    case C_INT16: 
    case C_INT32: 
    case C_INT64: 
    case C_UINT8: 
    case C_UINT16: 
    case C_UINT32: 
    case C_UINT64: 
    case C_DOUBLE: 
    case C_BOOL: 
    case C_ENUM_VALUE:
    case C_BINARY: 
    case C_DECIMAL64: 
    case C_IPV4: 
    case C_IPV6: 
    case C_IPV4PREFIX:
    case C_IPV4_AND_PLEN: 
    case C_IPV6_AND_PLEN: 
    case C_IPV6PREFIX: {

      struct confd_type *ct = cs_node->info.type;
      
      int len = confd_val2str (ct, child_src, value, sizeof (value));
      if (len < 0) {
        return RW_TREE_WALKER_FAILURE;
      }
      val_p = &value[0];
    }
      
      break;
    case C_LIST: {
      
      // ATTN: ATTN:
      // This code is inefficient. TAIL-F has been asked what the best method
      // for doing this is. Once TAILF responds, change this code.

      // ATTN: ATTN:
      // This also needs to change when protobuf representation of a leaf list
      // transitions to becoming a list of single elements
      

      struct confd_type *ct = confd_get_leaf_list_type (cs_node);
      RW_ASSERT(ct);
      
      int len = confd_val2str (ct, child_src, value, sizeof (value));
      if (len < 0) {
        return RW_TREE_WALKER_FAILURE;
      }
      val_p = &value[0];
    }
      break;
  }
  child = parent->add_child (child_yn, val_p);
  if (child) {
    return RW_TREE_WALKER_SUCCESS;
  }

  return RW_TREE_WALKER_FAILURE;
}
Beispiel #18
0
rw_tree_walker_status_t add_pbcm_child (ProtobufCMessage *parent,
                                        rw_confd_value_t *confd,
                                        ProtobufCFieldInfo *child_tgt,
                                        bool find_field)
{

  if (find_field) {
    memset (child_tgt, 0, sizeof (ProtobufCFieldInfo));
    const char *name = confd_hash2str (confd->cs_node->tag);
    const char *ns = confd_hash2str (confd->cs_node->ns);
    
    child_tgt->fdesc = protobuf_c_message_descriptor_get_field_by_yang (
        parent->descriptor, name, ns);
  }

  child_tgt->element = nullptr;
  child_tgt->len = 0;
  
  RW_ASSERT(child_tgt->fdesc);


  confd_cs_node *cs_node = confd->cs_node;
  confd_value_t *child_src = confd->value;

  uint32_t v_uint32 = 0;
  int32_t v_int32 = 0;
  uint64_t v_uint64 = 0;
  int64_t v_int64 = 0;
  double v_double = 0.0;
  protobuf_c_boolean v_bool = 0;

  switch (child_src->type) {
    default:
    case C_NOEXISTS:
    case C_STR:
    case C_SYMBOL: 
      RW_CRASH();
    break;
    
    case C_XMLTAG: 
      // Empty in YANG, bool in pbcm
      v_bool = 1;
      child_tgt->element = &v_bool;      
      break;

    case C_BUF: 
      child_tgt->element = CONFD_GET_BUFPTR(child_src);
      child_tgt->len = CONFD_GET_BUFSIZE(child_src);
      break;
      
    case C_INT8: 
      v_int32 = (int32_t)CONFD_GET_INT8 (child_src);
      child_tgt->element = &v_int32;
      break;
      
    case C_INT16: 
      v_int32 = (int32_t)CONFD_GET_INT16 (child_src);
      child_tgt->element = &v_int32;
      break;

    case C_INT32: 
      v_int32 = CONFD_GET_INT32 (child_src);
      child_tgt->element = &v_int32;
      break;
      
    case C_INT64: 
      v_int64 = CONFD_GET_INT64 (child_src);
      child_tgt->element = &v_int64;
      break;
      
    case C_UINT8: 
      v_uint32 = (uint32_t)CONFD_GET_UINT8 (child_src);
      child_tgt->element = &v_uint32;
      break;
 
    case C_UINT16: 
      v_uint32 = (uint32_t)CONFD_GET_UINT16 (child_src);
      child_tgt->element = &v_uint32;
      break;
      
    case C_UINT32: 
      v_uint32 = CONFD_GET_UINT32 (child_src);
      child_tgt->element = &v_uint32;
      break;
      
    case C_UINT64: 
      v_uint64 = CONFD_GET_UINT64 (child_src);
      child_tgt->element = &v_uint64;
      break;
      
    case C_DOUBLE: 
      v_double = CONFD_GET_DOUBLE (child_src);
      child_tgt->element = &v_double;
      break;
      
    case C_BOOL: 
      v_bool = CONFD_GET_BOOL(child_src);
      child_tgt->element = &v_bool;
      break;
      
    case C_QNAME: 
      RW_CRASH();
      break;
      
    case C_DATETIME: 
      RW_CRASH();
      break;
      
    case C_DATE: 
      RW_CRASH();
      break;
      
    case C_TIME: 
      RW_CRASH();
      break;
 
    case C_DURATION:
      RW_CRASH();
      break;
    case C_ENUM_VALUE: 
      v_uint32 = (uint32_t) CONFD_GET_ENUM_VALUE (child_src);
      child_tgt->element = &v_uint32;
      break;
      
    case C_BIT32: 
      RW_CRASH();
      break;
    case C_BIT64: 
      RW_CRASH();
      break;
      
    case C_LIST: {
      
      // ATTN: ATTN:
      // This code is inefficient. TAIL-F has been asked what the best method
      // for doing this is. Once TAILF responds, change this code.

      // ATTN: ATTN:
      // This also needs to change when protobuf representation of a leaf list
      // transitions to becoming a list of single elements
      
      char value[1024];
      struct confd_type *ct = confd_get_leaf_list_type (cs_node);
      RW_ASSERT(ct);
      
      int len = confd_val2str (ct, child_src, value, sizeof (value));
      if (len < 0) {
        return RW_TREE_WALKER_FAILURE;
      }
      
      bool ok = protobuf_c_message_set_field_text_value (
          nullptr, parent, child_tgt->fdesc, value, len);
      if (ok) {
        return RW_TREE_WALKER_SUCCESS;
      } else {
        return RW_TREE_WALKER_FAILURE;
      }
    }
      break;
    case C_XMLBEGIN:  {
      // Add a message 
      bool ok = protobuf_c_message_set_field_message (
          nullptr, parent, child_tgt->fdesc, (ProtobufCMessage **) &child_tgt->element);
      if (ok) {
        return RW_TREE_WALKER_SUCCESS;
      } else {
        return RW_TREE_WALKER_FAILURE;
      }
    }          
      break;
      
    case C_XMLEND: 
      RW_CRASH();
      break;
    case C_OBJECTREF: 
      RW_CRASH();
      break;
    case C_UNION: 
      RW_CRASH();
      break;
    case C_PTR: 
      RW_CRASH();
      break;
 
    case C_CDBBEGIN: 
      RW_CRASH();
      break;
    case C_OID: 
      RW_CRASH();
      break;
    case C_BINARY: 
      child_tgt->element = CONFD_GET_BINARY_PTR(child_src);
      child_tgt->len = CONFD_GET_BINARY_SIZE(child_src);
      break;
      
    case C_DECIMAL64: 
    case C_IPV4: 
    case C_IPV6: 
    case C_IPV4PREFIX:
    case C_IPV4_AND_PLEN: 
    case C_IPV6_AND_PLEN: 
    case C_IPV6PREFIX: {
      
      char value[1024];
      struct confd_type *ct = cs_node->info.type;

      int len = confd_val2str (ct, child_src, value, sizeof (value));
      if (len < 0) {
        return RW_TREE_WALKER_FAILURE;
      }
      
      bool ok = protobuf_c_message_set_field_text_value (
          nullptr, parent, child_tgt->fdesc, value, len);
      if (ok) {
        return RW_TREE_WALKER_SUCCESS;
      } else {
        return RW_TREE_WALKER_FAILURE;
      }
    }
      break;
    case C_DEFAULT: 
      RW_CRASH();
      break;
      
    case C_IDENTITYREF: 
      RW_CRASH();
      break;
    case C_XMLBEGINDEL: 
      RW_CRASH();
      break;
 
    case C_DQUAD: 
      RW_CRASH();
      break;
    case C_HEXSTR: 
      RW_CRASH();
      break;
  }

  bool ok = protobuf_c_message_set_field (nullptr, parent, child_tgt);
  if (ok) {
    return RW_TREE_WALKER_SUCCESS;
  }

  return RW_TREE_WALKER_FAILURE;

  
}
Beispiel #19
0
static rwdts_member_rsp_code_t rwdts_appconf_xact_event(rwdts_api_t *apih,
                                                        rwdts_group_t *grp,
                                                        rwdts_xact_t *xact,
                                                        rwdts_member_event_t xact_event, /* PRECOMMIT/COMMIT/ABORT/... */
                                                        void *ctx,
                                                        void *scratch_in) {
  rwdts_appconf_xact_t *appx = (rwdts_appconf_xact_t *)scratch_in;
  RW_ASSERT_TYPE(appx, rwdts_appconf_xact_t);
  rwdts_appconf_t *ac = appx->ac;
  int k;

  switch (xact_event) {
    default:
      break;
    case RWDTS_MEMBER_EVENT_ABORT:
      appx->abort++;
      RW_ASSERT(appx->abort == 1);
      RW_ASSERT(appx->commit == 0);
      appx->errs_ct = 0;

      /* Apply with xact=NULL to revert*/
      if (ac->cb.xact_init_dtor) {
        ac->cb.config_apply_gi(apih,
                               ac,
                               NULL,
                               RWDTS_APPCONF_ACTION_INSTALL,
                               ac->cb.ctx,
                               NULL);
      } else {
        ac->cb.config_apply(apih,
                            ac,
                            NULL,
                            RWDTS_APPCONF_ACTION_INSTALL,
                            ac->cb.ctx,
                            NULL);
      }
      if (appx->errs_ct) {
        // Whoops, now we're doomed
        RWDTS_API_LOG_XACT_EVENT(apih, xact, RwDtsApiLog_notif_AppconfInstallFailed,
                                 "Appconf INSTALL failure", appx->errs_ct, rwdts_get_app_addr_res(apih, ac->cb.config_apply), apih->client_path);
        int i;
        for (i=0; i<appx->errs_ct; i++) {
          RWDTS_API_LOG_XACT_EVENT(apih, xact, RwDtsApiLog_notif_AppconfInstallErrors,
                                   i, appx->errs[i].rs, appx->errs[i].str);
        }
        RW_CRASH();
      }
      break;

    case RWDTS_MEMBER_EVENT_PRECOMMIT:
      appx->precommit++;
      RW_ASSERT(appx->precommit == 1);
      RW_ASSERT(appx->commit == 0);
      RW_ASSERT(appx->abort == 0);

      /* Validate */
      if (ac->cb.config_validate) {
        if (ac->cb.xact_init_dtor) {
          ac->cb.config_validate_gi(apih,
                                    ac,
                                    (rwdts_xact_t*)xact,
                                    ac->cb.ctx,
                                    appx->scratch);
        } else {
          ac->cb.config_validate(apih,
                                 ac,
                                 (rwdts_xact_t*)xact,
                                 ac->cb.ctx,
                                 appx->scratch);
        }
      }
      if (appx->errs_ct) {
        /* How to actually get xact->appconf->err[] table up to uagent etc? */
        return RWDTS_ACTION_NOT_OK;
      }

      /* Reconcile */
      if (ac->cb.xact_init_dtor) {
        ac->cb.config_apply_gi(apih,
                               ac,
                               (rwdts_xact_t*)xact,
                               RWDTS_APPCONF_ACTION_RECONCILE,
                               ac->cb.ctx,
                               appx->scratch);
      } else {
        ac->cb.config_apply(apih,
                            ac,
                            (rwdts_xact_t*)xact,
                            RWDTS_APPCONF_ACTION_RECONCILE,
                            ac->cb.ctx,
                            appx->scratch);
      }
      if (!appx->errs_ct) {
        return RWDTS_ACTION_OK;
      }

      /* How to actually get xact->appconf->err[] table up to uagent etc? */
      for (k = 0; k < appx->errs_ct;free(appx->errs[k].str),k++);
      free(appx->errs);
      appx->errs = NULL;
      appx->errs_ct = 0;

      return RWDTS_ACTION_NOT_OK;        /* will trigger PRECOMMIT -> ABORT */
      break;
    case RWDTS_MEMBER_EVENT_COMMIT:
      appx->commit++;
      RW_ASSERT(appx->commit == 1);
      RW_ASSERT(appx->precommit == 1);
      RW_ASSERT(appx->abort == 0);
      break;
  }

  return RWDTS_ACTION_OK;
}