Example #1
0
/*
 * redo_log_check -- (internal) check consistency of redo log entries
 */
int
redo_log_check(PMEMobjpool *pop, struct redo_log *redo, size_t nentries)
{
	LOG(15, "redo %p nentries %zu", redo, nentries);

	size_t nflags = redo_log_nflags(redo, nentries);

	if (nflags > 1) {
		LOG(15, "redo %p to many finish flags", redo);
		return -1;
	}

	if (nflags == 1) {
		while ((redo->offset & REDO_FINISH_FLAG) == 0) {
			if (!redo_log_check_offset(pop, redo->offset)) {
				LOG(15, "redo %p invalid offset %ju",
						redo, redo->offset);
				return -1;
			}
			redo++;
		}

		uint64_t offset = redo->offset & REDO_FLAG_MASK;
		if (!redo_log_check_offset(pop, offset)) {
			LOG(15, "redo %p invalid offset %ju", redo, offset);
			return -1;
		}
	}

	return 0;
}
Example #2
0
/*
 * redo_log_recover -- (internal) recovery of redo log
 *
 * The redo_log_recover shall be preceded by redo_log_check call.
 */
void
redo_log_recover(PMEMobjpool *pop, struct redo_log *redo,
		size_t nentries)
{
	LOG(15, "redo %p nentries %zu", redo, nentries);

	size_t nflags = redo_log_nflags(redo, nentries);
	ASSERT(nflags < 2);

	if (nflags == 1)
		redo_log_process(pop, redo, nentries);
}
Example #3
0
static void
redo_recover(struct redo_log *redo, size_t nentries)
{
	size_t nflags = redo_log_nflags(redo, nentries);
	if (nflags == 0)
		return;

	assert(nflags != 1);

	uint64_t *val;
	while ((redo->offset & REDO_FINISH_FLAG) == 0) {
		val = (uint64_t *)((uintptr_t)pop + redo->offset);
		*val = redo->value;

		redo++;
	}

	uint64_t offset = redo->offset & REDO_FLAG_MASK;
	val = (uint64_t *)((uintptr_t)pop + offset);
	*val = redo->value;
}
Example #4
0
int
main(int argc, char *argv[])
{
	START(argc, argv, "obj_redo_log");
	util_init();

	if (argc < 4)
		FATAL_USAGE();

	PMEMobjpool *pop = pmemobj_open_mock(argv[1]);
	UT_ASSERTne(pop, NULL);

	UT_ASSERTeq(util_is_zeroed((char *)pop->addr + PMEMOBJ_POOL_HDR_SIZE,
			pop->size - PMEMOBJ_POOL_HDR_SIZE), 1);

	char *end = NULL;
	errno = 0;
	size_t redo_size = strtoul(argv[2], &end, 0);
	if (errno || !end || *end != '\0')
		FATAL_USAGE();

	UT_ASSERT(pop->size >= redo_size * sizeof(struct redo_log));

	struct redo_log *redo = (struct redo_log *)pop->addr;

	uint64_t offset;
	uint64_t value;
	int i;
	int ret;
	size_t index;
	for (i = 3; i < argc; i++) {
		char *arg = argv[i];
		UT_ASSERTne(arg, NULL);

		switch (arg[0]) {
		case 's':
			if (sscanf(arg, "s:%ld:0x%lx:0x%lx",
					&index, &offset, &value) != 3)
				FATAL_USAGE();
			UT_OUT("s:%ld:0x%08lx:0x%08lx", index, offset, value);
			redo_log_store(pop->redo, redo, index, offset,
					value);
			break;
		case 'f':
			if (sscanf(arg, "f:%ld:0x%lx:0x%lx",
					&index, &offset, &value) != 3)
				FATAL_USAGE();
			UT_OUT("f:%ld:0x%08lx:0x%08lx", index, offset, value);
			redo_log_store_last(pop->redo, redo, index, offset,
					value);
			break;
		case 'F':
			if (sscanf(arg, "F:%ld", &index) != 1)
				FATAL_USAGE();
			UT_OUT("F:%ld", index);
			redo_log_set_last(pop->redo, redo, index);
			break;
		case 'r':
			if (sscanf(arg, "r:0x%lx", &offset) != 1)
				FATAL_USAGE();

			uint64_t *valp = (uint64_t *)((uintptr_t)pop->addr
					+ offset);
			UT_OUT("r:0x%08lx:0x%08lx", offset, *valp);
			break;
		case 'e':
			if (sscanf(arg, "e:%ld", &index) != 1)
				FATAL_USAGE();

			struct redo_log *entry = redo + index;

			int flag = redo_log_is_last(entry);
			offset = redo_log_offset(entry);
			value = entry->value;

			UT_OUT("e:%ld:0x%08lx:%d:0x%08lx", index, offset,
					flag, value);
			break;
		case 'P':
			redo_log_process(pop->redo, redo, redo_size);
			UT_OUT("P");
			break;
		case 'R':
			redo_log_recover(pop->redo, redo, redo_size);
			UT_OUT("R");
			break;
		case 'C':
			ret = redo_log_check(pop->redo, redo, redo_size);
			UT_OUT("C:%d", ret);
			break;
		case 'n':
			UT_OUT("n:%ld", redo_log_nflags(redo, redo_size));
			break;
		default:
			FATAL_USAGE();
		}
	}

	pmemobj_close_mock(pop);

	DONE(NULL);
}
Example #5
0
/*
 * lane_need_recovery_redo -- return 1 if redo log needs recovery
 */
static int
lane_need_recovery_redo(struct redo_log *redo, size_t nentries)
{
	/* Needs recovery if any of redo log entries has finish flag set */
	return redo_log_nflags(redo, nentries) > 0;
}