summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/commit2.c16
-rw-r--r--src/common/common.h2
-rw-r--r--src/common/unionfs.c213
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;
+}