summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMichael Larson <slioch@slioch.vyatta.com>2010-04-22 13:34:17 -0700
committerMichael Larson <slioch@slioch.vyatta.com>2010-04-22 13:34:17 -0700
commitb72ddf64bc5d89487ffe9672f0ba89c5b90ac2e5 (patch)
tree23b4f9af8dfd915c8951729fd3bb0dbf9e658fb7 /src
parentd29097a8800e16899873bea1b70b85b0bd3586ab (diff)
downloadvyatta-cfg-b72ddf64bc5d89487ffe9672f0ba89c5b90ac2e5.tar.gz
vyatta-cfg-b72ddf64bc5d89487ffe9672f0ba89c5b90ac2e5.zip
support for PARENT reference in priority statements. Example:
priority: PARENT Means that this priority group will adopt the priority value of the parent. And the behavior on deletion of this priority root node will be deleted before the parent. On all other operations this node will be scheduled after the parent. This should fix problems in scheduling creation/deletion orders for priority groups so long as they are located within the same hierarchy. priority.pl has been updated as well.
Diffstat (limited to 'src')
-rw-r--r--src/cli_def.l2
-rw-r--r--src/cli_parse.y9
-rw-r--r--src/cli_val.h1
-rw-r--r--src/commit2.c108
-rw-r--r--src/common/defs.h1
-rw-r--r--src/common/unionfs.c13
6 files changed, 124 insertions, 10 deletions
diff --git a/src/cli_def.l b/src/cli_def.l
index 721e5f0..804d142 100644
--- a/src/cli_def.l
+++ b/src/cli_def.l
@@ -257,6 +257,7 @@ RE_TYPE_NAME (txt|u32|ipv4|ipv4net|ipv6|ipv6net|bool|macaddr)
/* values */
RE_VAL_U32 [0-9]+
RE_VAL_BOOL (true|false)
+RE_VAL_TEXT [a-zA-Z]+
/* operators */
RE_OP_COND (==|!=|<|>|<=|>=|in)
@@ -444,6 +445,7 @@ RE_ACT_FIELD (help|syntax|commit|delete|update|activate|create|begin|end|comp_he
return VAR;
}
+<INITIAL,expression>{RE_VAL_TEXT} { return return_value(TEXT_TYPE); }
<INITIAL,expression>{RE_VAL_U32} { return return_value(INT_TYPE); }
<INITIAL,expression>{RE_IPV4} { return return_value(IPV4_TYPE); }
<INITIAL,expression>{RE_IPV4NET} { return return_value(IPV4NET_TYPE); }
diff --git a/src/cli_parse.y b/src/cli_parse.y
index db56d3e..0f32928 100644
--- a/src/cli_parse.y
+++ b/src/cli_parse.y
@@ -174,21 +174,18 @@ default_cause: DEFAULT STRING
yy_cli_parse_error((const char *)"Bad default\n");
parse_defp->def_default = $2;
}
-
priority_stmt: PRIORITY VALUE
{
char *tmp = $2.val;
- long long int cval = 0;
+ long long int cval = 0;
char *endp = NULL;
errno = 0;
cval = strtoll(tmp, &endp, 10);
- if (($2.val_type != INT_TYPE)
- || (errno == ERANGE
+ if ((errno == ERANGE
&& (cval == LLONG_MAX || cval == LLONG_MIN))
|| (errno != 0 && cval == 0)
|| (*endp != '\0') || (cval < 0) || (cval > UINT_MAX)) {
- yy_cli_parse_error((const char *)
- "Priority must be <u32>\n");
+ parse_defp->def_priority_ext = tmp;
} else {
parse_defp->def_priority = cval;
}
diff --git a/src/cli_val.h b/src/cli_val.h
index 408cc50..e6182e7 100644
--- a/src/cli_val.h
+++ b/src/cli_val.h
@@ -107,6 +107,7 @@ typedef struct {
char *def_node_help;
char *def_default;
unsigned int def_priority;
+ char *def_priority_ext;
unsigned int def_tag;
unsigned int def_multi;
boolean tag;
diff --git a/src/commit2.c b/src/commit2.c
index 40d9cc8..3db695f 100644
--- a/src/commit2.c
+++ b/src/commit2.c
@@ -52,6 +52,9 @@ gboolean
sort_func_priority(GNode *node, gpointer data);
gboolean
+sort_func_priority_extended(GNode *node, gpointer data);
+
+gboolean
sort_func_simple(GNode *node, gpointer data);
void
@@ -582,6 +585,92 @@ sort_func_simple(GNode *node, gpointer data)
*
**/
gboolean
+sort_func_priority_extended(GNode *node, gpointer data)
+{
+ const GNode *orig_config; //needs to be passed in
+
+ gpointer gp = ((GNode*)node)->data;
+ GNode *root_node = (GNode*)data;
+
+ //WILL STOP AT DEPTH OF 10 REFERENCES
+ //GET PARENT WORKING FIRST....
+
+ //change action state of node according to enclosing behavior
+ if (((struct VyattaNode*)gp)->_config._priority_extended != NULL) { //only if priority is specified.
+ GNode *new_node = g_node_copy(node);
+ int cur_pri = LOWEST_PRIORITY;
+
+ //NOW, we need to figure out where this node belongs in the priority chain
+ if (strncmp(((struct VyattaNode*)gp)->_config._priority_extended,"PARENT",6) == 0) {
+ //needs to walk up parents until priority is found and insert there....
+
+ //walk up chain until priority is found.
+ GNode *n = node;
+ while (TRUE) {
+ gpointer n_gpointer = ((GNode*)n)->data;
+ n = n->parent;
+ if (n == NULL) {
+ break;
+ }
+ gpointer nd = ((GNode*)n)->data;
+ if (((struct VyattaNode*)nd)->_config._priority != LOWEST_PRIORITY) {
+ //means we are done--found anchor in parent
+ g_node_unlink(node);
+ if (IS_DELETE(((struct VyattaNode*)gp)->_data._operation)) {
+ g_node_insert_before(root_node,n,new_node);
+ }
+ else {
+ g_node_insert_after(root_node,n,new_node);
+ }
+ break;
+ }
+ /*
+ else if (((struct VyattaNode*)gp)->_config._priority_extended != NULL) {
+ //need to find references in other node tree....
+
+ //PARSE OUT EXTENDED REFERENCES...
+ for (int i = 0; i < ct; ++i) {
+ //get dependency...what to do with dependencies on dependencies... might get big. recursion buddy....
+ if (find_reference_anchor(orig_config, ((struct VyattaNode*)gp)->_config._priority_extended, cur_pri) != 0) {
+ cur_pri = LOWEST_PRIORITY;
+ }
+ }
+ break;
+ }
+ */
+ }
+ }
+ else {
+ /*
+ //multiple dependencies should be placed outside the earliest (delete) or latest (create) reference
+ if (find_reference_anchor(orig_config, ((struct VyattaNode*)gp)->_config._priority_extended, cur_pri) != 0) {
+ cur_pri = LOWEST_PRIORITY;
+ }
+ */
+ }
+ /*
+ //finds location for insertion
+ while (sibling != NULL && cur_pri > ((struct VyattaNode*)(sibling->data))->_config._priority * 10) {
+ sibling = sibling->next;
+ if (sibling == NULL || ((struct VyattaNode*)gp)->_config._priority < ((struct VyattaNode*)(sibling->data))->_config._priority) {
+ break;
+ }
+ }
+
+ //I think that's it then...
+ g_node_insert_before(root_node,sibling,new_node);
+ }
+ */
+ }
+ return FALSE;
+}
+
+
+/**
+ *
+ *
+ **/
+gboolean
sort_func(GNode *node, gpointer data, boolean priority_mode)
{
gpointer gp = ((GNode*)node)->data;
@@ -708,6 +797,14 @@ get_transactions(GNode *config, boolean priority_mode)
if (g_node_n_children(config) != 0) {
g_node_insert(trans_root,-1,config); //add what's left
}
+
+ //now need pass to handle extended priority system
+ g_node_traverse(trans_root,
+ G_POST_ORDER,
+ G_TRAVERSE_ALL,
+ -1,
+ (GNodeTraverseFunc)sort_func_priority_extended,
+ (gpointer)trans_root);
}
else {
g_node_traverse(config,
@@ -812,11 +909,18 @@ dump_func(GNode *node, gpointer data)
fprintf(out," ");
}
if (((struct VyattaNode*)gp)->_config._def.def_type2 != NULL) {
- fprintf(out,"%s (t: %d-%d, p: %d)", ((struct VyattaNode*)gp)->_data._name,((struct VyattaNode*)gp)->_config._def.def_type,((struct VyattaNode*)gp)->_config._def.def_type2,((struct VyattaNode*)gp)->_config._priority);
+ fprintf(out,"%s (t: %d-%d, ", ((struct VyattaNode*)gp)->_data._name,((struct VyattaNode*)gp)->_config._def.def_type,((struct VyattaNode*)gp)->_config._def.def_type2);
+ }
+ else {
+ fprintf(out,"%s (t: %d, ", ((struct VyattaNode*)gp)->_data._name,((struct VyattaNode*)gp)->_config._def.def_type);
+ }
+ if (((struct VyattaNode*)gp)->_config._priority_extended != NULL) {
+ fprintf(out, "p: %s)",((struct VyattaNode*)gp)->_config._priority_extended);
}
else {
- fprintf(out,"%s (t: %d, p: %d)", ((struct VyattaNode*)gp)->_data._name,((struct VyattaNode*)gp)->_config._def.def_type,((struct VyattaNode*)gp)->_config._priority);
+ fprintf(out, "p: %d)",((struct VyattaNode*)gp)->_config._priority);
}
+
if (((struct VyattaNode*)gp)->_data._value == TRUE) {
fprintf(out," [VALUE]");
}
diff --git a/src/common/defs.h b/src/common/defs.h
index 8c68c1d..6f97e9b 100644
--- a/src/common/defs.h
+++ b/src/common/defs.h
@@ -55,6 +55,7 @@ struct Config
{
boolean _multi;
int _priority;
+ char* _priority_extended;
int _limit;
vtw_def _def; //keep this here
char* _help;
diff --git a/src/common/unionfs.c b/src/common/unionfs.c
index 2220d73..2be210e 100644
--- a/src/common/unionfs.c
+++ b/src/common/unionfs.c
@@ -154,7 +154,7 @@ void
retrieve_data(char* rel_data_path, GNode *node, char* root, NODE_OPERATION op)
{
boolean final_node = FALSE;
-
+
if (node == NULL) {
return;
}
@@ -223,6 +223,7 @@ retrieve_data(char* rel_data_path, GNode *node, char* root, NODE_OPERATION op)
printf("[FOUND node.def]");
syslog(LOG_DEBUG,"[FOUND node.def]");
}
+
//either multi or tag--shouldn't have made a difference, but arkady was confused.
vn->_config._multi = (def.tag | def.multi);
if (def.def_tag > 0) {
@@ -278,11 +279,11 @@ retrieve_data(char* rel_data_path, GNode *node, char* root, NODE_OPERATION op)
}
}
-
if (G_NODE_IS_ROOT(node) == FALSE) {
struct VyattaNode* vn_parent = (struct VyattaNode*)node->parent->data;
struct VyattaNode* vn = (struct VyattaNode*)node->data;
// vn->_config._priority = vn_parent->_config._def.def_priority;
+
if (vn->_config._def.tag && vn->_config._multi) {
vn->_config._priority = LOWEST_PRIORITY;
}
@@ -292,6 +293,13 @@ retrieve_data(char* rel_data_path, GNode *node, char* root, NODE_OPERATION op)
else {
vn->_config._priority = vn->_config._def.def_priority;
}
+
+ if (vn->_config._def.tag && vn->_config._multi) {
+ vn->_config._priority_extended = '\0';
+ }
+ else {
+ vn->_config._priority_extended = vn->_config._def.def_priority_ext;
+ }
}
@@ -896,6 +904,7 @@ copy_vyatta_node(struct VyattaNode* vn)
new_vn->_data._operation = vn->_data._operation;
new_vn->_config._multi = vn->_config._multi;
new_vn->_config._priority = vn->_config._priority;
+ new_vn->_config._priority_extended = vn->_config._priority_extended;
// new_vn->_config._def = new_vn->_config._def; //cpy this?
if (vn->_config._default != NULL) {
new_vn->_config._default = malloc(MAX_LENGTH_DIR_PATH*sizeof(char));