Exemple #1
0
/* This routine looks at a pairs of facts at a given time step such that 
   neither fact is in the initial state, and returns 1 if they cannot both 
   be created by ops in this time step.

   Note: be sure to skip over the noops here.  
*/
int are_facts_excl_in_this_step(vertex_t v1, vertex_t v2)
{
  edgelist_t e1, e2;
  for(e1 = v1->in_edges; e1; e1 = e1->next) {
    if (IS_NOOP(e1->endpt)) continue;
    for(e2 = v2->in_edges; e2; e2 = e2->next) {
      if (IS_NOOP(e2->endpt)) continue;
      if (!are_mutex(e1->endpt, e2->endpt)) return 0;
    }
  }
  return 1;
}
Exemple #2
0
/************ ROUTINES FOR PRINTING OUT INFORMATION TO USER**************/
void print_info_piece(hashtable_t t, int flag)
{
  vertex_t vert;
  edgelist_t edge;
  get_next(t, 0); /* get ready */
  while((vert = get_next(t, 1)) != NULL) {
    if (vert->needed == 0 || IS_NOOP(vert)) continue;
    printf("%s\n",vert->name);
    if (flag>=2 && ((edge = vert->exclusive) != NULL)) {
      printf("   exclusive: "); /* now, includes noops */
      for(; edge; edge = edge->next)
	if (edge->endpt->needed) printf("%s ",edge->endpt->name);
      printf("\n");
    }
  }
}
Exemple #3
0
gboolean
sort_func(GNode *node, gpointer data, boolean priority_mode)
{
  struct VyattaNode *gp = (struct VyattaNode *) node->data;
  struct Data *d = &(gp->_data);
  GNode *root_node = (GNode*)data;
  d_dplog("commit2::sort_func(): %s, node count: %d",
          (d->_name ?  d->_name : "[n/a]"), g_node_n_children(root_node));

  //change action state of node according to enclosing behavior
  /* XXX this is ugly. originally the condition for the if is the following:
   *       (c1 && c2 || (c3 || c4) && c5)
   *
   *     this causes compiler warning for mixing && and || without (). the
   *     previous warning removal attempt changed the condition to the
   *     following:
   *       ((c1 && c2) || (c3 || (c4 && c5)))
   *
   *     which was incorrect (c3 and c4 should be at the same "level") and
   *     therefore was reverted.
   *
   *     now changing the condition to the following to avoid compiler
   *     warning:
   *       ((c1 && c2) || ((c3 || c4) && c5))
   *
   *     note that since the current goal is simply cleanup, no attempt is
   *     made to understand the logic here, and the change is purely based
   *     on operator precendence to maintain the original logic.
   *
   * XXX now removing deactivate-handling code, which involves c2.
   *
   *     note that c2 is (d->_disable_op != K_NO_DISABLE_OP), which means
   *     the node is "deactivated" (in working or active config or both).
   *     this in turn means that the (c1 && c2) part of the logic can only
   *     be true if the node is deactivated.
   *
   *     however, since activate/deactivate has not actually been exposed,
   *     this means that in actual usage the (c1 && c2) part is never true.
   *     therefore, we can simply remove the whole part, and the logic
   *     becomes:
   *       ((c3 || c4) && c5)
   */
  NODE_OPERATION op = d->_operation;
  if (((/* c3 */ IS_SET_OR_CREATE(op)) || (/* c4 */ IS_DELETE(op)))
      && (/* c5 */ IS_NOOP(((struct VyattaNode*)
                             (node->parent->data))->_data._operation))) {
    //first check if there is enclosing behavior
    boolean enclosing = FALSE;
    GNode *n = node;
    while (TRUE) {
      n = n->parent;
      vtw_def def = ((struct VyattaNode*)(n->data))->_config._def;
      if (def.actions[end_act].vtw_list_head
          || def.actions[begin_act].vtw_list_head) {
        enclosing = TRUE;
        break;
      }
      if (G_NODE_IS_ROOT(n) == TRUE) {
        break;
      }
    }

    //walk back up and flip operations until enclosing behavior
    if (enclosing == TRUE) {
      GNode *n = node;
      while (TRUE) {
        n = n->parent;
        vtw_def def = ((struct VyattaNode*)(n->data))->_config._def;
        if (((struct VyattaNode*)(n->data))->_data._operation == K_NO_OP) {
          /* XXX this is ugly. _operation is intended to be a bitmap, in which
           *     case it doesn't make sense to make it an enum type (should
           *     just be, e.g., int). this causes g++ to (rightly) complain.
           *     work around it for now to avoid impacting other code since
           *     the current goal is simply cleanup.
           */
          int op = ((struct VyattaNode*)(n->data))->_data._operation;
          op |= K_ACTIVE_OP;
          ((struct VyattaNode*)(n->data))->_data._operation
            = (NODE_OPERATION) op;
        }
        if (def.actions[end_act].vtw_list_head
            || def.actions[begin_act].vtw_list_head) {
          break;
        }
        if (G_NODE_IS_ROOT(n) == TRUE) {
          break;
        }
      }
    }
  }

  if (priority_mode) {
    int gprio = gp->_config._priority;
    if (gprio < LOWEST_PRIORITY) {
      // only if priority is specified.
      //unlink from original tree
      g_node_unlink(node);

      GNode *new_node = g_node_copy(node);
      GNode *sibling = root_node->children;
      //now iterate through siblings of root_node and compare priority
      
      while (sibling
             && gprio > ((struct VyattaNode*)(sibling->data))
                        ->_config._priority) {
        sibling = sibling->next;
        if (!sibling
            || gprio < ((struct VyattaNode*)(sibling->data))
                       ->_config._priority) {
          // XXX isn't this redundant??? just cleaning up so not changing it
          break;
        }
      }

      d_dplog("commit2::sort_func(): inserting %s into transaction, "
              "priority: %d BEFORE %d", d->_name, gprio,
              (sibling
               ? ((struct VyattaNode*)(sibling->data))->_config._priority
                 : LOWEST_PRIORITY));
      g_node_insert_before(root_node,sibling,new_node);
    }
  }
  else {
    if (g_node_depth(node) == 2) {
      d_dplog("commit2::sort_func(): insert %s into transaction", d->_name);
      GNode *new_node = g_node_copy(node);
      g_node_insert(root_node,-1,new_node); //make a flat structure for now
    }
  }
  return FALSE;
}
Exemple #4
0
/**
 * Execute syntax and commit checks
 **/
static gboolean
validate_func(GNode *node, gpointer data)
{
  if (node == NULL) {
    return TRUE;
  }

  struct VyattaNode *gp = (struct VyattaNode *) node->data;
  struct Config *c = &(gp->_config);
  struct Data *d = &(gp->_data);
  struct Aux *a = &(gp->_aux);
  struct Result *result = (struct Result*)data;

  /* let's mark first last nodes here for use later
   * do first/last/only sibling check, restrict to nodes with operations
   * defined
   */
  GNode *n_last_op = NULL;
  GNode *n_first_op = NULL;
  
  GNode *sib = g_node_first_sibling(node);
  while (sib != NULL) {
    if (IS_DELETE(((struct VyattaNode*)(sib->data))->_data._operation)) {
      if (n_first_op == NULL) {
        n_first_op = sib;
      }
      n_last_op = sib;
    }
    sib = sib->next;
  }

  sib = g_node_first_sibling(node);
  while (sib != NULL) {
    if (IS_SET_OR_CREATE(((struct VyattaNode*)(sib->data))
                         ->_data._operation)) {
      if (n_first_op == NULL) {
        n_first_op = sib;
      }
      n_last_op = sib;
    }
    sib = sib->next;
  }

  a->_first = (node == n_first_op);
  a->_last = (node == n_last_op);


  /* since this visits all working nodes, let's maintain a set of nodes
   * to commit
   */
  GSList *coll = (GSList*)result->_data;
  if (d->_path != NULL) {
    char buf[MAX_LENGTH_DIR_PATH*sizeof(char)];
    if (IS_DELETE(d->_operation)) {
      sprintf(buf,"- %s",d->_path);
      if (c->_def.multi) {
        /* need to handle the embedded multinode as a special
         * case--should be fixed!
         */
        char *val = (char*)clind_unescape(d->_name);
        strcat(buf,val);
        free(val);
      }
      char *tmp = (char *) malloc(strlen(buf)+1);
      strcpy(tmp,buf);
      coll = g_slist_append(coll,tmp);
      result->_data = (void*)coll;
    }
    else if (IS_SET_OR_CREATE(d->_operation)) {
      sprintf(buf,"+ %s",d->_path);
      if (c->_def.multi) {
        /* need to handle the embedded multinode as a special
         * case--should be fixed!
         */
        char *val = (char*)clind_unescape(d->_name);
        strcat(buf,val);
        free(val);
      }
 
      char *tmp = (char *) malloc(strlen(buf)+1);
      strcpy(tmp,buf);
      coll = g_slist_append(coll,tmp);
      result->_data = (void*)coll;
    }
  }
  
  //don't run syntax check on this node if it is unchanged.
  if (IS_NOOP(d->_operation) && c->_def.actions[syntax_act].vtw_list_head
      && !c->_def.actions[syntax_act].vtw_list_head->vtw_node_aux) {
    return FALSE;
  }
  
  if (IS_DELETE(d->_operation) && !IS_ACTIVE(d->_operation)) {
    return FALSE; //will not perform validation checks on deleted nodes
  }

  if (!c->_def.actions  ||
      !c->_def.actions[result->_action].vtw_list_head){
    return FALSE;
  }

  /* will not call term multi if it is a noop--shouldn't show up in tree
   * in the first place, but will require more rework of unionfs code
   * to fix this.
   */
  if (c->_def.multi && IS_NOOP(d->_operation)) {
    return FALSE;
  }
  
  //look at parent for multi tag
  if (d->_value && d->_name) {
    char *val = d->_name;
    if (c->_def.tag) {
      /* need to handle the embedded multinode as a special
       * case--should be fixed!
       */
      val = (char*)clind_unescape(d->_name);
    }
    d_dplog("commit2::process_func(): @ value: %s",(char *) val);

    set_at_string(val); //embedded multinode value
  }
  else {
    if (g_debug) {
      dplog("commit2::process_func(): boolean value is: %d", d->_value);
      if (node->parent
          && ((struct VyattaNode*)(node->parent->data))->_data._name) {
        dplog("commit2::process_func(): parent has a name: %s",
              ((struct VyattaNode*)(node->parent->data))->_data._name);
      }
      dplog("commit2::process_func(): @ value: [NULL]");
    }
  }

  common_set_context(c->_path,d->_path);
  d_dplog("Executing %s on this node", ActionNames[result->_action]);
  
  if (g_coverage) {
    struct timeval t;
    gettimeofday(&t,NULL);
    fprintf(out_stream, "[START] %lu:%lu, %s@%s", (unsigned long) t.tv_sec,
            (unsigned long) t.tv_usec, ActionNames[result->_action], d->_path);
  }

  boolean status = 1;
  if (g_dump_actions == FALSE) {
    //set location env
    setenv(ENV_DATA_PATH,d->_path,1);
    if (g_old_print_output == TRUE) {
      status
        = execute_list(c->_def.actions[result->_action].vtw_list_head,
                       &c->_def, NULL);
    } else {
      char *p = process_script_path(d->_path);
      status
        = execute_list(c->_def.actions[result->_action].vtw_list_head,
                       &c->_def, p);
      free(p);
    }
    unsetenv(ENV_DATA_PATH);
  }
  else {
    char buf[MAX_LENGTH_DIR_PATH*sizeof(char)];
    if (c->_def.actions[syntax_act].vtw_list_head) {
      if (c->_def.actions[syntax_act].vtw_list_head->vtw_node_aux == 0) {
        sprintf(buf,"syntax\t:\t%s",d->_path);
      }
      else {
        sprintf(buf,"commit\t:\t%s",d->_path);
      }
    }
    if (c->_def.multi) {
      /* need to handle the embedded multinode as a special
       * case--should be fixed!
       */
      char *val = (char*)clind_unescape(d->_name);
      strcat(buf,val);
      free(val);
    }
    fprintf(out_stream,"%s\n",buf);
    status = 1;
  }

  if (g_coverage) {
    struct timeval t;
    gettimeofday(&t,NULL);
    fprintf(out_stream,"[END] %lu:%lu\n",t.tv_sec,t.tv_usec);
  }
  
  if (!status) { //EXECUTE_LIST RETURNS FALSE ON FAILURE....
    syslog(LOG_ERR, "commit error for %s:[%s]",
           ActionNames[result->_action], d->_path);
    if (g_display_error_node) {
      fprintf(out_stream, "%s@_errloc_:[%s]\n",
              ActionNames[result->_action], d->_path);
    }
    result->_err_code = 1;
    d_dplog("commit2::validate_func(): FAILURE: status: %d", status);
    // WILL STOP AT THIS POINT if mode is not set for full syntax check
    return result->_mode ? FALSE: TRUE;
  }
  return FALSE;
}