summaryrefslogtreecommitdiff
path: root/src/common
diff options
context:
space:
mode:
authorslioch <slioch@eng-140.vyatta.com>2009-02-24 13:08:52 -0800
committerslioch <slioch@eng-140.vyatta.com>2009-02-24 13:08:52 -0800
commit91a4c9f9093a5ef5d0baf792dd94a3f4e15d4488 (patch)
treea25f47f1ccd5391e8e343a1135429365f0f6b726 /src/common
parentb7098025c671a543f37cc3156194bdef8a0ad5c6 (diff)
downloadvyatta-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/common')
-rw-r--r--src/common/common.h2
-rw-r--r--src/common/unionfs.c213
2 files changed, 172 insertions, 43 deletions
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;
+}