fixed commit

This commit is contained in:
Olof hagsand 2016-02-22 23:07:30 +01:00
parent d6e393ea58
commit 33fac8a4c6
4 changed files with 23 additions and 959 deletions

View file

@ -192,8 +192,16 @@ candidate_commit(clicon_handle h,
if (plugin_transaction_commit(h, td) < 0)
goto done;
/* 8. Copy running back to candidate in case end functions triggered
updates in running */
/* 8. Success: Copy candidate to running */
if (file_cp(candidate, running) < 0){
clicon_err(OE_UNIX, errno, "file_cp(candidate; running)");
goto done;
}
/* 9. Call plugin transaction end callbacks */
plugin_transaction_end(h, td);
/* 8. Copy running back to running in case end functions updated running */
if (file_cp(running, candidate) < 0){
/* ignore errors or signal major setback ? */
clicon_err(OE_UNIX, errno, "file_cp(running, candidate)");
@ -201,279 +209,6 @@ candidate_commit(clicon_handle h,
goto done;
}
/* 9. Call plugin transaction end callbacks */
plugin_transaction_end(h, td);
#ifdef OBSOLETE
/* Find the differences between the two databases and store it in df vector. */
memset(&df, 0, sizeof(df));
if (db_diff(running, candidate,
__FUNCTION__,
clicon_dbspec_key(h),
&df
) < 0)
goto done;
if (debug){
struct dbdiff_ent *dfe;
for (i=0; i<df.df_nr; i++) {
dfe = &df.df_ents[i];
clicon_debug(1, "%s op:%d key:%s",
__FUNCTION__,
dfe->dfe_op,
cvec_name_get(dfe->dfe_vec1?dfe->dfe_vec1:dfe->dfe_vec2));
}
}
/* 1. Get commit processing to dbdiff vector: one entry per key that changed.
changes are registered as if they exist in the 1st(candidate) or
2nd(running) dbs.
*/
if (dbdep_commitvec(h, &df, &nvec, &ddvec) < 0)
goto done;
/* 2. Call transaction_begin hooks */
if (plugin_transaction_begin(h) < 0)
goto done;
/* call generic cv_validate() on all new or changed keys. */
if (generic_validate(yspec, NULL) < 0)
goto done;
/* user-defined validate callbacks registered in dbdep_validate */
// if (validate_db(h, nvec, ddvec, running, candidate) < 0)
// goto done;
/* Call plugin post-commit hooks */
if (plugin_transaction_complete(h) < 0)
goto done;
if (clicon_commit_order(h) == 0){
for (i=0; i < nvec; i++){ /* revert in opposite order */
dd = &ddvec[i];
dp = dd->dd_dep; /* op, callback, arg */
if ((dp->dp_type & TRANS_CB_COMMIT) == 0)
continue;
dfe = dd->dd_dbdiff; /* key1/key2/op */
op = dbdiff2commit_op(dfe->dfe_op);
if (plugin_commit_callback(h,
op, /* oper */
running, /* db1 */
candidate, /* db2 */
dd->dd_mkey1, /* key1 */
dd->dd_mkey2, /* key2 */
dd->dd_dbdiff->dfe_vec1, /* vec1 */
dd->dd_dbdiff->dfe_vec2, /* vec2 */
dp /* callback */
) < 0){
firsterr = clicon_err_save(); /* save this error */
failed++;
break;
}
}
if (!failed)
if (file_cp(candidate, running) < 0){ /* Commit here in case cp fails */
clicon_err(OE_UNIX, errno, "file_cp");
failed++;
}
/* Failed operation, start error handling: rollback in opposite order */
if (failed){
for (j=i-1; j>=0; j--){ /* revert in opposite order */
dd = &ddvec[j];
dp = dd->dd_dep; /* op, callback, arg */
if ((dp->dp_type & TRANS_CB_COMMIT) == 0)
continue;
dfe = dd->dd_dbdiff; /* key1/key2/op */
op = dbdiff2commit_op(dfe->dfe_op);
switch (op){ /* reverse operation */
case CO_ADD:
op = CO_DELETE;
break;
case CO_DELETE:
op = CO_ADD;
break;
default:
break;
}
if (plugin_commit_callback(h,
op, /* oper */
candidate, /* db1 */
running, /* db2 */
dd->dd_mkey2, /* key1 */
dd->dd_mkey1, /* key2 */
dd->dd_dbdiff->dfe_vec2, /* vec1 */
dd->dd_dbdiff->dfe_vec1, /* vec2 */
dp /* callback */
) < 0){
/* ignore errors or signal major setback ? */
clicon_log(LOG_NOTICE, "Error in rollback, trying to continue");
continue;
}
}
goto done;
} /* error handling */
}
else { /* commit_order == 1 or 2 */
/* Now follows commit rules in order.
* 4. For all keys that are not in candidate but in running, delete key
* in reverse prio order
*/
for (i = nvec-1; i >= 0; i--){
dd = &ddvec[i];
dp = dd->dd_dep; /* op, callback, arg */
if ((dp->dp_type & TRANS_CB_COMMIT) == 0)
continue;
dfe = dd->dd_dbdiff; /* key1/key2/op */
op = dbdiff2commit_op(dfe->dfe_op);
/* original mode 2 where CHANGE=DEL/ADD */
if (clicon_commit_order(h) == 2 && op == CO_CHANGE)
op = CO_DELETE;
if (op != CO_DELETE)
continue;
if (plugin_commit_callback(h,
op, /* oper */
running, /* db1 */
candidate, /* db2 */
dd->dd_mkey1, /* key1 */
dd->dd_mkey2, /* key2 */
dd->dd_dbdiff->dfe_vec1, /* vec1 */
dd->dd_dbdiff->dfe_vec2, /* vec2 */
dp /* callback */
) < 0){
firsterr = clicon_err_save(); /* save this error */
break;
}
}
/* 5. Failed deletion, add the key value back to running */
if (i >= 0){ /* failed */
for (j=i+1; j<nvec; j++){ /* revert in opposite order */
dd = &ddvec[j];
dp = dd->dd_dep; /* op, callback, arg */
if ((dp->dp_type & TRANS_CB_COMMIT) == 0)
continue;
dfe = dd->dd_dbdiff; /* key1/key2/op */
op = dbdiff2commit_op(dfe->dfe_op);
/* original mode 2 where CHANGE=DEL/ADD */
if (clicon_commit_order(h) == 2 && op == CO_CHANGE)
op = CO_DELETE;
if (op != CO_DELETE)
continue;
if (plugin_commit_callback(h,
op, /* oper */
candidate, /* db1 */
running, /* db2 */
dd->dd_mkey2, /* key1 */
dd->dd_mkey1, /* key2 */
dd->dd_dbdiff->dfe_vec2, /* vec1 */
dd->dd_dbdiff->dfe_vec1, /* vec2 */
dp /* callback */
) < 0){
/* ignore errors or signal major setback ? */
clicon_log(LOG_NOTICE, "Error in rollback, trying to continue");
continue;
}
}
goto done;
}
/*
* 6. For all added or changed keys
*/
for (i=0; i < nvec; i++){
dd = &ddvec[i];
dp = dd->dd_dep; /* op, callback, arg */
if ((dp->dp_type & TRANS_CB_COMMIT) == 0)
continue;
dfe = dd->dd_dbdiff; /* key1/key2/op */
op = dbdiff2commit_op(dfe->dfe_op);
if (op != CO_CHANGE && op != CO_ADD)
continue;
/* original mode 2 where CHANGE=DEL/ADD */
if (clicon_commit_order(h) == 2 && op == CO_CHANGE)
op = CO_ADD;
if (plugin_commit_callback(h,
op, /* oper */
running, /* db1 */
candidate, /* db2 */
dd->dd_mkey1, /* key1 */
dd->dd_mkey2, /* key2 */
dd->dd_dbdiff->dfe_vec1, /* vec1 */
dd->dd_dbdiff->dfe_vec2, /* vec2 */
dp /* callback */
) < 0){
firsterr = clicon_err_save(); /* save this error */
failed++;
break;
}
}
if (!failed) /* Commit here in case cp fails */
if (file_cp(candidate, running) < 0){
clicon_err(OE_UNIX, errno, "file_cp(candidate; running)");
failed++;
}
/* 10. Failed setting keys in running, first remove the keys set */
if (failed){ /* failed */
for (j=i-1; j>=0; j--){ /* revert in opposite order */
dd = &ddvec[j];
dp = dd->dd_dep; /* op, callback, arg */
if ((dp->dp_type & TRANS_CB_COMMIT) == 0)
continue;
dfe = dd->dd_dbdiff; /* key1/key2/op */
op = dbdiff2commit_op(dfe->dfe_op);
if (op != CO_CHANGE && op != CO_ADD)
continue;
/* original mode 2 where CHANGE=DEL/ADD */
if (clicon_commit_order(h) == 2 && op == CO_CHANGE)
op = CO_ADD;
if (op == CO_ADD) /* reverse op */
op = CO_DELETE;
if (plugin_commit_callback(h,
op, /* oper */
candidate, /* db1 */
running, /* db2 */
dd->dd_mkey2, /* key1 */
dd->dd_mkey1, /* key2 */
dd->dd_dbdiff->dfe_vec2, /* vec1 */
dd->dd_dbdiff->dfe_vec1, /* vec2 */
dp /* callback */
) < 0){
/* ignore errors or signal major setback ? */
clicon_log(LOG_NOTICE, "Error in rollback, trying to continue");
continue;
}
}
for (j=0; j < nvec; j++){ /* revert in opposite order */
dd = &ddvec[j];
dp = dd->dd_dep; /* op, callback, arg */
if ((dp->dp_type & TRANS_CB_COMMIT) == 0)
continue;
dfe = dd->dd_dbdiff; /* key1/key2/op */
op = dbdiff2commit_op(dfe->dfe_op);
/* original mode 2 where CHANGE=DEL/ADD */
if (clicon_commit_order(h) == 2 && op == CO_CHANGE)
op = CO_DELETE;
if (op != CO_DELETE)
continue;
op = CO_ADD;
if (plugin_commit_callback(h,
op, /* oper */
candidate, /* db1 */
running, /* db2 */
dd->dd_mkey2, /* key1 */
dd->dd_mkey1, /* key2 */
dd->dd_dbdiff->dfe_vec2, /* vec1 */
dd->dd_dbdiff->dfe_vec1, /* vec2 */
dp /* callback */
) < 0){
/* ignore errors or signal major setback ? */
clicon_log(LOG_NOTICE, "Error in rollback, trying to continue");
continue;
}
}
goto done;
}
} /* commit_order */
#endif /* OBSOLETE */
retval = 0;
done:
/* In case of failure, call plugin transaction termination callbacks */