summaryrefslogtreecommitdiff
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
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.
-rw-r--r--scripts/priority.pl32
-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
7 files changed, 154 insertions, 12 deletions
diff --git a/scripts/priority.pl b/scripts/priority.pl
index 4124987..0cadbc3 100644
--- a/scripts/priority.pl
+++ b/scripts/priority.pl
@@ -9,6 +9,7 @@ use warnings;
use File::Find;
my %priorities;
+my @parent_priorities;
# Open node file and extract priority and comment if any
sub get_priority {
@@ -19,7 +20,7 @@ sub get_priority {
while (<$f>) {
chomp;
- next unless m/^priority:\s(\d+)/;
+ next unless m/^priority:\s((PARENT)|(\d+))/;
$priority = $1;
$comment = $1 if (/#(.*)$/);
@@ -47,7 +48,12 @@ sub wanted {
if $comment;
# append line to list of entries with same priority
- push @{ $priorities{$priority} }, $dir;
+ if ($priority ne 'PARENT') {
+ push @{ $priorities{$priority} }, $dir;
+ }
+ else {
+ push(@parent_priorities, $dir);
+ }
return 1;
}
@@ -58,6 +64,28 @@ die "$cfgdir does not exist!" unless -d $cfgdir;
# walk config file tree
find( \&wanted, $cfgdir );
+#resolve parent dependencies
+foreach my $pp (@parent_priorities) {
+ my $tmp = $pp;
+ while (1) {
+ my $pos = rindex($tmp, "/");
+ if ($pos == -1) {
+ last;
+ }
+ $tmp = substr($tmp,0,$pos);
+
+ #search through second value in collection for match
+ foreach (keys %priorities) {
+ foreach my $a (@{ $priorities{$_} }) {
+ if ($a eq $tmp) {
+ push @{ $priorities{$_} }, $pp . " [PARENT]";
+ last;
+ }
+ }
+ }
+ }
+}
+
# display resulting priorities
foreach my $key ( sort { $a <=> $b } keys %priorities ) {
my @a = @{ $priorities{$key} };
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));