fixed commit
This commit is contained in:
parent
d6e393ea58
commit
33fac8a4c6
4 changed files with 23 additions and 959 deletions
|
|
@ -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 */
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue