/* * from_client_commit * Handle an incoming commit message from a client. * XXX: If commit succeeds and snapshot/startup fails, we have strange state: * the commit has succeeded but an error message is returned. */ int from_client_commit(clicon_handle h, int s, struct clicon_msg *msg, const char *label) { char *candidate, *running; uint32_t snapshot, startup; int retval = -1; char *snapshot_0; if (clicon_msg_commit_decode(msg, &candidate, &running, &snapshot, &startup, label) < 0) goto err; if (candidate_commit(h, candidate, running) < 0){ clicon_debug(1, "Commit %s failed", candidate); retval = 0; /* We ignore errors from commit, but maybe we should fail on fatal errors? */ goto err; } clicon_debug(1, "Commit %s", candidate); if (snapshot && config_snapshot(clicon_dbspec_key(h), running, clicon_archive_dir(h)) < 0) goto err; if (startup){ snapshot_0 = chunk_sprintf(__FUNCTION__, "%s/0", clicon_archive_dir(h)); if (file_cp(snapshot_0, clicon_startup_config(h)) < 0){ clicon_err(OE_PROTO, errno, "%s: Error when creating startup", __FUNCTION__); goto err; } } retval = 0; if (send_msg_ok(s) < 0) goto done; goto done; err: /* XXX: more elaborate errstring? */ if (send_msg_err(s, clicon_errno, clicon_suberrno, "%s", clicon_err_reason) < 0) retval = -1; done: unchunk_group(__FUNCTION__); return retval; /* may be zero if we ignoring errors from commit */ } /* from_client_commit */
/*! Reset running and start in failsafe mode. If no failsafe then quit. Typically done when startup status is not OK so failsafe ----------------------+ reset \ commit running |-------+---------------> RUNNING FAILSAFE */ int startup_failsafe(clicon_handle h) { int retval = -1; int ret; char *db = "failsafe"; cbuf *cbret = NULL; if ((cbret = cbuf_new()) == NULL){ clicon_err(OE_XML, errno, "cbuf_new"); goto done; } if ((ret = xmldb_exists(h, db)) < 0) goto done; if (ret == 0){ /* No it does not exist, fail */ clicon_err(OE_DB, 0, "Startup failed and no Failsafe database found, exiting"); goto done; } /* Copy original running to tmp as backup (restore if error) */ if (xmldb_copy(h, "running", "tmp") < 0) goto done; if (startup_db_reset(h, "running") < 0) goto done; ret = candidate_commit(h, db, cbret); if (ret != 1) if (xmldb_copy(h, "tmp", "running") < 0) goto done; if (ret < 0) goto done; if (ret == 0){ clicon_err(OE_DB, 0, "Startup failed, Failsafe database validation failed %s", cbuf_get(cbret)); goto done; } clicon_log(LOG_NOTICE, "Startup failed, Failsafe database loaded "); retval = 0; done: if (cbret) cbuf_free(cbret); return retval; }