Exemplo n.º 1
0
/*
 * 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 */
Exemplo n.º 2
0
/*! 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;
}