Example #1
0
SV* call_ftn(SV* arg) {
	append_to_log_file(refcount_to_string("Refcount 3 (inside the callee):", SvREFCNT(arg)));
	FILE* fp;
	fp = fopen("print_scalar.txt", "w");
	fprintf(fp, "%s", SvPV_nolen(arg));
	fclose(fp);
	SvREFCNT_dec(arg);
	append_to_log_file(refcount_to_string("Refcount 4 (inside the callee, after dec):", SvREFCNT(arg)));
	return arg;
}
Example #2
0
static int
receive_loop (krb5_context context,
	      krb5_storage *sp,
	      kadm5_server_context *server_context)
{
    int ret;
    off_t left, right, off;
    uint32_t len, vers;

    if (verbose)
        krb5_warnx(context, "receiving diffs");

    /*
     * Seek to the first entry in the message from the master that is
     * past the current version of the local database.
     */
    do {
	uint32_t timestamp;
        uint32_t op;

        if ((ret = krb5_ret_uint32(sp, &vers)) == HEIM_ERR_EOF) {
            krb5_warnx(context, "master sent no new iprop entries");
            return 0;
        }

        /*
         * TODO We could do more to validate the entries from the master
         * here.  And we could use/reuse more kadm5_log_*() code here.
         *
         * Alternatively we should trust that the master sent us exactly
         * what we needed and just write this to the log file and let
         * kadm5_log_recover() do the rest.
         */
	if (ret || krb5_ret_uint32(sp, &timestamp) != 0 ||
            krb5_ret_uint32(sp, &op) != 0 ||
            krb5_ret_uint32(sp, &len) != 0) {

            /*
             * This shouldn't happen.  Reconnecting probably won't help
             * if it does happen, but by reconnecting we get a chance to
             * connect to a new master if a new one is configured.
             */
            krb5_warnx(context, "iprop entries from master were truncated");
            return EINVAL;
        }
	if (vers > server_context->log_context.version) {
            break;
        }
        off = krb5_storage_seek(sp, 0, SEEK_CUR);
        if (krb5_storage_seek(sp, len + 8, SEEK_CUR) != off + len + 8) {
            krb5_warnx(context, "iprop entries from master were truncated");
            return EINVAL;
        }
        if (verbose) {
            krb5_warnx(context, "diff contains old log record version "
                       "%u %lld %u length %u",
                       vers, (long long)timestamp, op, len);
        }
    } while(vers <= server_context->log_context.version);

    /*
     * Read the remaining entries into memory...
     */
    /* SEEK_CUR is a header into the first entry we care about */
    left  = krb5_storage_seek(sp, -16, SEEK_CUR);
    right = krb5_storage_seek(sp, 0, SEEK_END);
    if (right - left < 24 + len) {
        krb5_warnx(context, "iprop entries from master were truncated");
        return EINVAL;
    }

    /*
     * ...and then write them out to the on-disk log.
     */

    ret = append_to_log_file(context, server_context, sp, left, right - left);
    if (ret)
        return ret;

    /*
     * Replay the new entries.
     */
    if (verbose)
        krb5_warnx(context, "replaying entries from master");
    ret = kadm5_log_recover(server_context, kadm_recover_replay);
    if (ret) {
        krb5_warn(context, ret, "replay failed");
        return ret;
    }

    ret = kadm5_log_get_version(server_context, &vers);
    if (ret) {
        krb5_warn(context, ret,
                  "could not get log version after applying diffs!");
        return ret;
    }
    if (verbose)
        krb5_warnx(context, "slave at version %u", vers);

    if (vers != server_context->log_context.version) {
        krb5_warnx(context, "slave's log_context version (%u) is "
                   "inconsistent with log's version (%u)",
                   server_context->log_context.version, vers);
    }

    return 0;
}