diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/commit2.c | 78 | ||||
-rw-r--r-- | src/common/defs.h | 7 | ||||
-rw-r--r-- | src/common/unionfs.c | 49 | ||||
-rw-r--r-- | src/common/unionfs.h | 1 |
4 files changed, 112 insertions, 23 deletions
diff --git a/src/commit2.c b/src/commit2.c index 3db695f..af01598 100644 --- a/src/commit2.c +++ b/src/commit2.c @@ -363,6 +363,7 @@ process_func(GNode *node, gpointer data) gpointer gp = ((GNode*)node)->data; struct Config *c = &((struct VyattaNode*)gp)->_config; struct Data *d = &((struct VyattaNode*)gp)->_data; + NODE_OPERATION op = d->_operation; int status = 0; if (c->_def.actions && @@ -370,15 +371,32 @@ process_func(GNode *node, gpointer data) if (g_debug) { if (d->_name != NULL) { - printf("commit2::process_func(), calling process on : %s for action %d, type: %d, operation: %d, path: %s\n",d->_name,result->_action,c->_def.def_type, d->_operation, d->_path); - syslog(LOG_DEBUG,"commit2::process_func(), calling process on : %s for action %d, type: %d, operation: %d, path: %s",d->_name,result->_action,c->_def.def_type, d->_operation, d->_path); + printf("commit2::process_func(), calling process on : %s for action %d, type: %d, operation: %d, path: %s\n",d->_name,result->_action,c->_def.def_type, op, d->_path); + syslog(LOG_DEBUG,"commit2::process_func(), calling process on : %s for action %d, type: %d, operation: %d, path: %s",d->_name,result->_action,c->_def.def_type, op, d->_path); } else { - printf("commit2::process_func(), calling process on : [n/a] for action %d, operation: %d, path: %s\n",result->_action, d->_operation, d->_path); - syslog(LOG_DEBUG,"commit2::process_func(), calling process on : [n/a] for action %d, operation: %d, path: %s",result->_action, d->_operation, d->_path); + printf("commit2::process_func(), calling process on : [n/a] for action %d, operation: %d, path: %s\n",result->_action, op, d->_path); + syslog(LOG_DEBUG,"commit2::process_func(), calling process on : [n/a] for action %d, operation: %d, path: %s",result->_action, op, d->_path); } } + //FIRST LET'S COMPUTE THE DEACTIVATE->ACTIVATE OVERRIDE + if (d->_disable_op != K_NO_DISABLE_OP) { + if ((d->_disable_op & K_LOCAL_DISABLE_OP) && (d->_disable_op & K_ACTIVE_DISABLE_OP)) { + //no state change: deactivated + return FALSE; //skip operation on node + } + else if (!(d->_disable_op & K_LOCAL_DISABLE_OP) && (d->_disable_op & K_ACTIVE_DISABLE_OP)) { + //node will be activated on commit + //LET'S SPOOF the operation... convert it to CREATE + op = K_CREATE_OP; + } + else if ((d->_disable_op & K_LOCAL_DISABLE_OP) && !(d->_disable_op & K_ACTIVE_DISABLE_OP)) { + //node will be deactivated on commit + //LET'S SPOOF the operation... convert it to DELETE + op = K_DEL_OP; + } + } /* Needs to be cleaned up a bit such that this convoluted if clause is easier to read. Basically is says: @@ -388,15 +406,15 @@ process_func(GNode *node, gpointer data) or if a node is DELETE, is a DELETE ACTION or a END ACTION, or a BEGIN ACTION */ - if ((IS_SET(d->_operation) && !IS_ACTIVE(d->_operation) && (result->_action != delete_act && result->_action != create_act)) || - (IS_CREATE(d->_operation) && !IS_ACTIVE(d->_operation) && (result->_action == begin_act || result->_action == end_act || result->_action == create_act || (result->_action == update_act && !c->_def.actions[create_act].vtw_list_head))) || - (IS_ACTIVE(d->_operation) && ((result->_action == begin_act) || (result->_action == end_act))) || - (IS_DELETE(d->_operation) && ((result->_action == delete_act) || (result->_action == begin_act) || (result->_action == end_act)) )) { + if ((IS_SET(op) && !IS_ACTIVE(op) && (result->_action != delete_act && result->_action != create_act)) || + (IS_CREATE(op) && !IS_ACTIVE(op) && (result->_action == begin_act || result->_action == end_act || result->_action == create_act || (result->_action == update_act && !c->_def.actions[create_act].vtw_list_head))) || + (IS_ACTIVE(op) && ((result->_action == begin_act) || (result->_action == end_act))) || + (IS_DELETE(op) && ((result->_action == delete_act) || (result->_action == begin_act) || (result->_action == end_act)) )) { //NEED TO ADD IF CREATE, THEN CREATE OR UPDATE //IF SET THEN UPDATE //let's skip the case where this is active and it's a delete--shouldn't be done, but needs to be include in the rule set above - if (IS_DELETE(d->_operation) && IS_ACTIVE(d->_operation) && result->_action == delete_act) { + if (IS_DELETE(op) && IS_ACTIVE(op) && result->_action == delete_act && d->_disable_op == K_NO_DISABLE_OP) { //only apply this when no disable operation is set return FALSE; } @@ -475,8 +493,8 @@ process_func(GNode *node, gpointer data) } //do not set for promoted actions - if (!IS_ACTIVE(d->_operation)) { - if (IS_DELETE(d->_operation)) { + if (!IS_ACTIVE(op)) { + if (IS_DELETE(op)) { setenv(ENV_ACTION_NAME,ENV_ACTION_DELETE,1); } else { @@ -688,6 +706,7 @@ sort_func(GNode *node, gpointer data, boolean priority_mode) //change action state of node according to enclosing behavior if ((G_NODE_IS_ROOT(node) == FALSE) && + (((struct VyattaNode*)gp)->_data._disable_op != K_NO_DISABLE_OP) || //added to support enclosing behavior of activated/deactivated nodes ((IS_SET_OR_CREATE(((struct VyattaNode*)gp)->_data._operation)) || (IS_DELETE(((struct VyattaNode*)gp)->_data._operation))) && (IS_NOOP(((struct VyattaNode*)(node->parent->data))->_data._operation))) { @@ -713,7 +732,11 @@ sort_func(GNode *node, gpointer data, boolean priority_mode) while (TRUE) { n = n->parent; vtw_def def = ((struct VyattaNode*)(n->data))->_config._def; - ((struct VyattaNode*)(n->data))->_data._operation = ((struct VyattaNode*)gp)->_data._operation | K_ACTIVE_OP; + ((struct VyattaNode*)(n->data))->_data._operation = ((struct VyattaNode*)gp)->_data._operation; + //DON'T set active when only in disable state... + if (((struct VyattaNode*)gp)->_data._disable_op == K_NO_DISABLE_OP) { + ((struct VyattaNode*)(n->data))->_data._operation |= K_ACTIVE_OP; + } if (def.actions[end_act].vtw_list_head || def.actions[begin_act].vtw_list_head) { break; } @@ -890,21 +913,37 @@ dump_func(GNode *node, gpointer data) if (((struct VyattaNode*)gp)->_data._name != NULL) { int i; + char disable_op[2]; + if (((struct VyattaNode*)gp)->_data._disable_op == (K_ACTIVE_DISABLE_OP | K_LOCAL_DISABLE_OP)) { + disable_op[0] = 'c'; + } + else if (((struct VyattaNode*)gp)->_data._disable_op == K_ACTIVE_DISABLE_OP) { + disable_op[0] = 'u'; + } + else if (((struct VyattaNode*)gp)->_data._disable_op == K_LOCAL_DISABLE_OP) { + disable_op[0] = 's'; + } + else { + disable_op[0] = ' '; + } + disable_op[1] = '\0'; + if (IS_ACTIVE(((struct VyattaNode*)gp)->_data._operation)) { - fprintf(out,"*"); + fprintf(out,"%s*",disable_op); } else if (IS_DELETE(((struct VyattaNode*)gp)->_data._operation)) { - fprintf(out,"-"); + fprintf(out,"%s-",disable_op); } else if (IS_CREATE(((struct VyattaNode*)gp)->_data._operation)) { - fprintf(out,"+"); + fprintf(out,"%s+",disable_op); } else if (IS_SET(((struct VyattaNode*)gp)->_data._operation)) { - fprintf(out,">"); + fprintf(out,"%s>",disable_op); } else { - fprintf(out," "); + fprintf(out,"%s ",disable_op); } + for (i = 0; i < depth; ++i) { fprintf(out," "); } @@ -1171,6 +1210,11 @@ validate_func(GNode *node, gpointer data) } } + //don't perform validation checks on disabled nodes + if (d->_disable_op == K_LOCAL_DISABLE_OP) { + return FALSE; //SHOULD only hit the case where the node is locally disabled or globally disabled and not in a transition to active state + } + if (IS_DELETE(d->_operation) && !IS_ACTIVE(d->_operation)) { return FALSE; //will not perform validation checks on deleted nodes } diff --git a/src/common/defs.h b/src/common/defs.h index 6f97e9b..88b8441 100644 --- a/src/common/defs.h +++ b/src/common/defs.h @@ -35,6 +35,12 @@ typedef enum { K_DEL_OP = 0x10 } NODE_OPERATION; +typedef enum { + K_NO_DISABLE_OP = 0X00, + K_LOCAL_DISABLE_OP = 0x02, //MEANS DISABLE FLAG IS SET IN LOCAL CONFIGURATION + K_ACTIVE_DISABLE_OP = 0x04 //MEANS DISABLE FLAG IS SET IN ACTIVE CONFIGURATION +} NODE_ACTIVATE; + #define IS_SET(op) (op & K_SET_OP) #define IS_ACTIVE(op) (op & K_ACTIVE_OP) #define IS_CREATE(op) (op & K_CREATE_OP) @@ -72,6 +78,7 @@ struct Data boolean _value; //is this a value? char* _path; NODE_OPERATION _operation; //no-op, set, or delete + NODE_ACTIVATE _disable_op; //is this node currently deactivated? }; struct VyattaNode diff --git a/src/common/unionfs.c b/src/common/unionfs.c index 2be210e..151c6ce 100644 --- a/src/common/unionfs.c +++ b/src/common/unionfs.c @@ -189,6 +189,7 @@ retrieve_data(char* rel_data_path, GNode *node, char* root, NODE_OPERATION op) vn->_data._name = cp; vn->_data._value = FALSE;//TRUE; //data value vn->_data._operation = op; + vn->_data._disable_op = K_NO_DISABLE_OP; vn->_config._priority = LOWEST_PRIORITY; vn->_data._path = malloc(MAX_LENGTH_DIR_PATH*sizeof(char)); sprintf(vn->_data._path,"%s",rel_data_path); @@ -280,9 +281,7 @@ 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; @@ -343,19 +342,49 @@ retrieve_data(char* rel_data_path, GNode *node, char* root, NODE_OPERATION op) strcmp(dirp->d_name, "..") != 0 && strcmp(dirp->d_name, MODIFIED_FILE) != 0 && strcmp(dirp->d_name, DEF_FILE) != 0 && + strcmp(dirp->d_name, DISABLE_FILE) != 0 && strcmp(dirp->d_name, WHITEOUT_FILE) != 0 && strcmp(dirp->d_name, VALUE_FILE) != 0) { processed = TRUE; + + NODE_ACTIVATE deactivated = K_NO_DISABLE_OP; + if (G_NODE_IS_ROOT(node) == FALSE && ((struct VyattaNode*)node->data)->_data._disable_op != K_NO_DISABLE_OP) { + deactivated = ((struct VyattaNode*)node->data)->_data._disable_op; + } + else { //do a lstat check in the local dir + struct stat s; + char buf[MAX_LENGTH_HELP_STR]; + sprintf(buf,"%s/%s/%s/%s",get_mdirp(),rel_data_path,dirp->d_name,DISABLE_FILE); + if (lstat(buf,&s) == 0) { + //need to check existence of file in active configuration here as well! + deactivated |= K_LOCAL_DISABLE_OP; + } + sprintf(buf,"%s/%s/%s/%s",get_adirp(),rel_data_path,dirp->d_name,DISABLE_FILE); + if (lstat(buf,&s) == 0) { + deactivated |= K_ACTIVE_DISABLE_OP; + } + } + char *data_buf = malloc(MAX_LENGTH_DIR_PATH*sizeof(char)); - if (strncmp(dirp->d_name,DELETED_NODE,4) == 0) { - strcpy(data_buf,dirp->d_name+4); //SKIP THE .WH. + if (strncmp(dirp->d_name,DELETED_NODE,4) == 0 || + deactivated != K_NO_DISABLE_OP) { + + struct VyattaNode *vn = calloc(1,sizeof(struct VyattaNode)); + + if (strncmp(dirp->d_name,DELETED_NODE,4) == 0) { + strcpy(data_buf,dirp->d_name+4); //SKIP THE .WH. + vn->_data._operation = K_DEL_OP; + } + else { + strcpy(data_buf,dirp->d_name); + vn->_data._operation = K_NO_OP; + } //create new node and insert... - struct VyattaNode *vn = calloc(1,sizeof(struct VyattaNode)); vn->_data._name = data_buf; vn->_data._value = FALSE; - vn->_data._operation = K_DEL_OP; vn->_config._priority = LOWEST_PRIORITY; + vn->_data._disable_op = deactivated; char new_data_path[MAX_LENGTH_DIR_PATH]; sprintf(new_data_path,"%s/%s",rel_data_path,data_buf); @@ -374,6 +403,7 @@ retrieve_data(char* rel_data_path, GNode *node, char* root, NODE_OPERATION op) vn->_data._name = data_buf; vn->_data._value = FALSE; vn->_config._priority = LOWEST_PRIORITY; + vn->_data._disable_op = deactivated; char new_data_path[MAX_LENGTH_DIR_PATH]; sprintf(new_data_path,"%s/%s",rel_data_path,data_buf); @@ -444,6 +474,7 @@ retrieve_data(char* rel_data_path, GNode *node, char* root, NODE_OPERATION op) vn->_data._value = FALSE; vn->_data._operation = K_DEL_OP; vn->_config._priority = LOWEST_PRIORITY; + vn->_data._disable_op = K_NO_DISABLE_OP; GNode *new_node = g_node_new(vn); new_node = insert_sibling_in_order(node,new_node); @@ -473,6 +504,7 @@ common_get_local_session_data() struct VyattaNode *vn = calloc(1,sizeof(struct VyattaNode)); vn->_data._name = NULL; //root node has null vn->_data._operation = K_NO_OP; + vn->_data._disable_op = K_NO_DISABLE_OP; vn->_config._priority = LOWEST_PRIORITY; //create first node @@ -902,6 +934,7 @@ copy_vyatta_node(struct VyattaNode* vn) strcpy(new_vn->_data._path,vn->_data._path); } new_vn->_data._operation = vn->_data._operation; + new_vn->_data._disable_op = vn->_data._disable_op; new_vn->_config._multi = vn->_config._multi; new_vn->_config._priority = vn->_config._priority; new_vn->_config._priority_extended = vn->_config._priority_extended; @@ -1070,6 +1103,10 @@ dlist_test_func(GQuark key_id,gpointer data,gpointer user_data) strcpy(new_vn->_data._name,(char*)g_quark_to_string(key_id)); new_vn->_config._path = malloc(MAX_LENGTH_DIR_PATH*sizeof(char)); sprintf(new_vn->_config._path,"%s/node.tag",vn_parent->_config._path); + + //let's set this nodes disable_op to its parent's value. + new_vn->_data._disable_op = vn_parent->_data._disable_op; + new_vn->_data._operation = ((struct ValueData*)data)->_state; new_vn->_config._def = vn_parent->_config._def; } diff --git a/src/common/unionfs.h b/src/common/unionfs.h index 098ac41..2933deb 100644 --- a/src/common/unionfs.h +++ b/src/common/unionfs.h @@ -23,6 +23,7 @@ #define NODE_TAG_FILE "node.tag" #define VALUE_FILE "node.val" #define MODIFIED_FILE ".modified" +#define DISABLE_FILE ".disable" #define DEF_FILE "def" #define WHITEOUT_FILE ".wh.__dir_opaque" #define DELETED_NODE ".wh." |