diff options
author | slioch <slioch@eng-140.vyatta.com> | 2009-02-24 13:08:52 -0800 |
---|---|---|
committer | slioch <slioch@eng-140.vyatta.com> | 2009-02-24 13:08:52 -0800 |
commit | 91a4c9f9093a5ef5d0baf792dd94a3f4e15d4488 (patch) | |
tree | a25f47f1ccd5391e8e343a1135429365f0f6b726 /src | |
parent | b7098025c671a543f37cc3156194bdef8a0ad5c6 (diff) | |
download | vyatta-cfg-91a4c9f9093a5ef5d0baf792dd94a3f4e15d4488.tar.gz vyatta-cfg-91a4c9f9093a5ef5d0baf792dd94a3f4e15d4488.zip |
replace unionfs synchronization code with piecewise copy. this should fix most of the problems related to nested priorities (but not all). also moved node profiling output from debug file
to stdout
(when enabled by the -c flag).
Diffstat (limited to 'src')
-rw-r--r-- | src/commit2.c | 16 | ||||
-rw-r--r-- | src/common/common.h | 2 | ||||
-rw-r--r-- | src/common/unionfs.c | 213 |
3 files changed, 182 insertions, 49 deletions
diff --git a/src/commit2.c b/src/commit2.c index 82045fc..6d358c5 100644 --- a/src/commit2.c +++ b/src/commit2.c @@ -202,7 +202,10 @@ main(int argc, char** argv) printf("commit2: Starting new transaction processing pass on root:\n"); } } - + + //complete() now requires a undisturbed copy of the trans_child_node tree + GNode *comp_cp_node = g_node_copy(trans_child_node); + //on each priority node now execute actions if ((success = process_priority_node(trans_child_node)) == TRUE) { //this below copies the node directory from the local to active location @@ -211,7 +214,7 @@ main(int argc, char** argv) //no op, need better way to define true root } else { - complete(trans_child_node, test_mode); + complete(comp_cp_node, test_mode); } } @@ -321,7 +324,7 @@ process_func(GNode *node, gpointer data) if (g_coverage) { struct timeval t; gettimeofday(&t,NULL); - printf("[START] %lu, %s@%s",(unsigned long)t.tv_sec,ActionNames[result->_action],d->_path); + fprintf(out_stream,"[START] %lu, %s@%s",(unsigned long)t.tv_sec,ActionNames[result->_action],d->_path); } if (result->_action == delete_act) { @@ -335,7 +338,7 @@ process_func(GNode *node, gpointer data) if (g_coverage) { struct timeval t; gettimeofday(&t,NULL); - printf("[END] %lu\n",t.tv_sec); + fprintf(out_stream,"[END] %lu\n",t.tv_sec); } if (!status) { //EXECUTE_LIST RETURNS FALSE ON FAILURE.... @@ -363,14 +366,15 @@ complete(GNode *node, boolean test_mode) gpointer gp = ((GNode*)node)->data; if (g_debug) { if (((struct VyattaNode*)gp)->_data._name != NULL) { - printf("commit2::complete(): %s\n",((struct VyattaNode*)gp)->_data._name); + printf("commit2::complete():name: %s\n",((struct VyattaNode*)gp)->_data._name); + printf("commit2::complete():path: %s\n",((struct VyattaNode*)gp)->_data._path); } else { printf("commit2::complete()\n"); } } //on transactional nodes only, note to avoid calling this if a headless root - common_commit_copy_to_live_config(((struct VyattaNode*)gp)->_data._path, test_mode); + common_commit_copy_to_live_config(node, test_mode); return TRUE; } diff --git a/src/common/common.h b/src/common/common.h index c9cacc8..e3b7bdc 100644 --- a/src/common/common.h +++ b/src/common/common.h @@ -42,7 +42,7 @@ common_set_parent_context(char *cpath, char *dpath); * **/ void -common_commit_copy_to_live_config(char *path, boolean test_mode); +common_commit_copy_to_live_config(GNode *root_node, boolean test_mode); /** * diff --git a/src/common/unionfs.c b/src/common/unionfs.c index 7084893..7cdb03c 100644 --- a/src/common/unionfs.c +++ b/src/common/unionfs.c @@ -39,6 +39,13 @@ insert_sibling_in_order(GNode *parent, GNode *child); void piecewise_remove(char* cbuf_root, char* abuf_root, char* path, boolean test_mode); + +static gboolean +copy_func(GNode *node, gpointer data); + +static gboolean +delete_func(GNode *node, gpointer data); + /** * * @@ -508,21 +515,12 @@ set_path(char *path, boolean config) * IN CURRENT HIERARCHICAL STRUCTURE WITHOUT CHANGING HOW UNDERLYING * SYSTEM MAINTAINS DATA. * -original commands: - static const char format1[]="cp -r -f %s/* %s"; //mdirp, tmpp - static const char format2[]="sudo umount %s"; //mdirp - static const char format3[]="rm -f %s/" MOD_NAME " >&/dev/null ; /bin/true"; - //tmpp - static const char format4[]="rm -rf %s/{.*,*} >&/dev/null ; /bin/true"; //cdirp - static const char format5[]="rm -rf %s/{.*,*} >&/dev/null ; /bin/true"; //adirp - static const char format6[]="mv -f %s/* -t %s";//tmpp, adirp - static const char format7[]="sudo mount -t $UNIONFS -o dirs=%s=rw:%s=ro $UNIONFS %s"; //cdirp, adirp, mdirp - * **/ void -common_commit_copy_to_live_config(char *path, boolean test_mode) +common_commit_copy_to_live_config(GNode *node, boolean test_mode) { //first check for existence of path before committing + char *path = ((struct VyattaNode*)(node->data))->_data._path; if (g_debug) { printf("common_commit_copy_to_live_config(): %s\n",path); @@ -569,6 +567,7 @@ common_commit_copy_to_live_config(char *path, boolean test_mode) return; } + //mkdir temp merge sprintf(command,format0,tbuf); if (g_debug) { printf("%s\n",command); @@ -578,6 +577,7 @@ common_commit_copy_to_live_config(char *path, boolean test_mode) system(command); } + //cp merge to temp merge sprintf(command, format1, mbuf, tbuf); if (g_debug) { printf("%s\n",command); @@ -587,6 +587,7 @@ common_commit_copy_to_live_config(char *path, boolean test_mode) system(command); } + //unmount temp (i.e. rm merge) sprintf(command, format2, mbuf_root); if (g_debug) { printf("%s\n",command); @@ -596,6 +597,9 @@ common_commit_copy_to_live_config(char *path, boolean test_mode) system(command); } + //I DON'T THINK I NEED THIS.... + /* + //mkdir active sprintf(command,format0,abuf); if (g_debug) { printf("%s\n",command); @@ -604,41 +608,14 @@ common_commit_copy_to_live_config(char *path, boolean test_mode) if (test_mode == FALSE) { system(command); } + */ - piecewise_remove(cbuf_root,abuf_root,path,test_mode); - sprintf(command, format4, cbuf); - if (g_debug) { - printf("%s\n",command); - fflush(NULL); - } - if (test_mode == FALSE) { - system(command); - } - /* - sprintf(command, format5, abuf); - if (g_debug) { - printf("%s\n",command); - fflush(NULL); - } - if (test_mode == FALSE) { - system(command); - } - */ //special piecewise operation //walk down tree and perform command where siblings diverge btwn tbuf and abuf - - sprintf(command, format6, tbuf, abuf); - if (g_debug) { - printf("%s\n",command); - fflush(NULL); - } - if (test_mode == FALSE) { - system(command); - } - - - sprintf(command, format7, tbuf); + // piecewise_remove(cbuf_root,abuf_root,path,test_mode); + /* + sprintf(command, format4, cbuf); if (g_debug) { printf("%s\n",command); fflush(NULL); @@ -646,6 +623,8 @@ common_commit_copy_to_live_config(char *path, boolean test_mode) if (test_mode == FALSE) { system(command); } + */ + piecewise_copy(node, test_mode); sprintf(command, format8, cbuf_root,abuf_root,mbuf_root); if (g_debug) { @@ -1090,3 +1069,153 @@ insert_sibling_in_order(GNode *parent, GNode *child) GNode *new_node = g_node_insert_after(parent, sibling, child); return new_node; } + +//needed for iteration below +struct SrcDst { + char *_src; + char *_dst; + boolean _test_mode; +}; + +/** + * + **/ +void +piecewise_copy(GNode *root_node, boolean test_mode) +{ + struct SrcDst sd; + sd._src = get_tmpp(); //copy of merged config + sd._dst = get_adirp(); //active config + sd._test_mode = test_mode; + + //COPY FROM TOP DOWN + g_node_traverse(root_node, + G_PRE_ORDER, + G_TRAVERSE_ALL, + -1, + (GNodeTraverseFunc)copy_func, + (gpointer)&sd); + + //delete needs to apply to changes only as src + sd._src = get_cdirp(); //changes only config + //DELETE FROM BOTTOM UP, stop on finding children + g_node_traverse(root_node, + G_POST_ORDER, + G_TRAVERSE_ALL, + -1, + (GNodeTraverseFunc)delete_func, + (gpointer)&sd); +} + +/** + * + * + **/ +static gboolean +copy_func(GNode *node, gpointer data) +{ + if (node == NULL) { + return FALSE; + } + + char *command = malloc(MAX_LENGTH_DIR_PATH); + + struct SrcDst *sd = (struct SrcDst*)data; + static const char format[]="mkdir %s%s";/*tmpp, adirp*/ + static const char format_value[]="cp %s%snode.val %s%s.";/*tmpp, adirp*/ + char *path = ((struct VyattaNode*)(node->data))->_data._path; + + //might not work for terminating multinodes as the node.val won't be copied + if (((struct VyattaNode*)(node->data))->_data._value == TRUE && + ((struct VyattaNode*)(node->data))->_config._def.tag == FALSE) { + //THIS IS ONLY FOR NODE.VAL (or leafs, term multis) + char *parent_path = ((struct VyattaNode*)(node->parent->data))->_data._path; + sprintf(command,format_value,sd->_src,parent_path,sd->_dst,parent_path); + if (g_debug) { + printf("%s\n",command); + fflush(NULL); + } + if (sd->_test_mode == FALSE) { + system(command); + } + } + else { + if (!IS_DELETE(((struct VyattaNode*)(node->data))->_data._operation)) { + sprintf(command,format,sd->_dst,path); + if (g_debug) { + printf("%s\n",command); + fflush(NULL); + } + if (sd->_test_mode == FALSE) { + system(command); + } + } + } + free(command); + return FALSE; +} + +/** + * + * + **/ +static gboolean +delete_func(GNode *node, gpointer data) +{ + if (node == NULL) { + return FALSE; + } + + char *command = malloc(MAX_LENGTH_DIR_PATH); + + struct SrcDst *sd = (struct SrcDst*)data; + static const char format[]="rm -fv %s%s{*,.*} >&/dev/null;rmdir %s%s >&/dev/null ; /bin/true"; //need to remove opaque file. + static const char format_force_delete[]="rm -fv %s%s{*,.*} >&/dev/null;rm -fr %s%s >&/dev/null ; /bin/true"; //force delete as this is a delete operation with dependency + static const char delete_format[]="rm %s%s../.wh.%s >&/dev/null"; + + char *path = ((struct VyattaNode*)(node->data))->_data._path; + + //does this node have any children that have not been copied???? + + //NEED RM -FV on changes only directory!!!! for normal removal!!! + + + //WILL ONLY REMOVE DIRS WITHOUT CHILD DIRS--just what we want.. + sprintf(command,format,sd->_src,path,sd->_src,path); + if (g_debug) { + printf("%s\n",command); + fflush(NULL); + } + if (sd->_test_mode == FALSE) { + system(command); + } + + //if this is a deletion operation, need to remove + if (IS_DELETE(((struct VyattaNode*)(node->data))->_data._operation) && + !IS_ACTIVE(((struct VyattaNode*)(node->data))->_data._operation)) { + + //DO NOT PERFORM THIS STEP IF THERE ARE SUBDIRECTORIES (only the whiteout file) + + //remove .whiteout file in c directory if encountered in walk. + sprintf(command,delete_format,sd->_src,path,((struct VyattaNode*)(node->data))->_data._name); + if (g_debug) { + printf("%s\n",command); + fflush(NULL); + } + if (sd->_test_mode == FALSE) { + system(command); + } + //if delete then remove entry in active configuration! + sprintf(command,format_force_delete,sd->_dst,path,sd->_dst,path); + if (g_debug) { + printf("%s\n",command); + fflush(NULL); + } + if (sd->_test_mode == FALSE) { + system(command); + } + } + free(command); + + return FALSE; +} |