Пример #1
0
/*
 * ut_sighandler -- fatal signal handler
 */
void
ut_sighandler(int sig)
{
	UT_ERR("\n");
	UT_ERR("Signal %d, backtrace:", sig);
	ut_dump_backtrace();
	UT_ERR("\n");
	exit(128 + sig);
}
Пример #2
0
/*
 * mutex_write_worker -- (internal) write data with mutex
 */
static void *
mutex_write_worker(void *arg)
{
	for (unsigned run = 0; run < WORKER_RUNS; run++) {
		if (pmemobj_mutex_lock(&Mock_pop, &Test_obj->mutex)) {
			UT_ERR("pmemobj_mutex_lock");
			return NULL;
		}

		memset(Test_obj->data, (int)(uintptr_t)arg, DATA_SIZE);
		if (pmemobj_mutex_unlock(&Mock_pop, &Test_obj->mutex))
			UT_ERR("pmemobj_mutex_unlock");
	}

	return NULL;
}
Пример #3
0
/*
 * timed_check_worker -- (internal) check consistency with mutex
 */
static void *
timed_check_worker(void *arg)
{
	for (unsigned run = 0; run < WORKER_RUNS; run++) {

		int mutex_id = (int)(uintptr_t)arg % 2;
		PMEMmutex *mtx = mutex_id == LOCKED_MUTEX ?
				&Test_obj->mutex_locked : &Test_obj->mutex;

		struct timespec t1, t2, t_diff, abs_time;
		os_clock_gettime(CLOCK_REALTIME, &t1);
		abs_time = t1;
		abs_time.tv_nsec += TIMEOUT;
		if (abs_time.tv_nsec >= NANO_PER_ONE) {
			abs_time.tv_sec += abs_time.tv_nsec / NANO_PER_ONE;
			abs_time.tv_nsec %= NANO_PER_ONE;
		}

		int ret = pmemobj_mutex_timedlock(&Mock_pop, mtx, &abs_time);

		os_clock_gettime(CLOCK_REALTIME, &t2);

		if (mutex_id == LOCKED_MUTEX) {
			UT_ASSERTeq(ret, ETIMEDOUT);
			t_diff.tv_sec = t2.tv_sec - t1.tv_sec;
			t_diff.tv_nsec = t2.tv_nsec - t1.tv_nsec;

			if (t_diff.tv_nsec < 0) {
				--t_diff.tv_sec;
				t_diff.tv_nsec += NANO_PER_ONE;
			}
			UT_ASSERT(t_diff.tv_sec * NANO_PER_ONE +
					t_diff.tv_nsec >= TIMEOUT);

			return NULL;
		}

		if (ret == 0) {
			UT_ASSERTne(mutex_id, LOCKED_MUTEX);
			pmemobj_mutex_unlock(&Mock_pop, mtx);
		} else if (ret == ETIMEDOUT) {
			t_diff.tv_sec = t2.tv_sec - t1.tv_sec;
			t_diff.tv_nsec = t2.tv_nsec - t1.tv_nsec;

			if (t_diff.tv_nsec < 0) {
				--t_diff.tv_sec;
				t_diff.tv_nsec += NANO_PER_ONE;
			}
			UT_ASSERT(t_diff.tv_sec * NANO_PER_ONE +
					t_diff.tv_nsec >= TIMEOUT);
		} else {
			errno = ret;
			UT_ERR("!pmemobj_mutex_timedlock");
		}
	}

	return NULL;
}
Пример #4
0
/*
 * rwlock_check_worker -- (internal) check consistency with rwlock
 */
static void *
rwlock_check_worker(void *arg)
{
	for (unsigned run = 0; run < WORKER_RUNS; run++) {
		if (pmemobj_rwlock_rdlock(&Mock_pop, &Test_obj->rwlock)) {
			UT_ERR("pmemobj_rwlock_rdlock");
			return NULL;
		}
		uint8_t val = Test_obj->data[0];
		for (int i = 1; i < DATA_SIZE; i++)
			UT_ASSERTeq(Test_obj->data[i], val);

		if (pmemobj_rwlock_unlock(&Mock_pop, &Test_obj->rwlock))
			UT_ERR("pmemobj_rwlock_unlock");
	}

	return NULL;
}
Пример #5
0
/*
 * ut_dump_backtrace -- dump stacktrace to error log using libc's backtrace
 */
void
ut_dump_backtrace(void)
{
	int j, nptrs;
	void *buffer[SIZE];
	char **strings;

	nptrs = backtrace(buffer, SIZE);

	strings = backtrace_symbols(buffer, nptrs);
	if (strings == NULL) {
		UT_ERR("!backtrace_symbols");
		return;
	}

	for (j = 0; j < nptrs; j++)
		UT_ERR("%u: %s", j, strings[j]);

	free(strings);
}
Пример #6
0
/*
 * ut_dump_backtrace -- dump stacktrace to error log using libunwind
 */
void
ut_dump_backtrace(void)
{
	unw_context_t context;
	unw_proc_info_t pip;

	pip.unwind_info = NULL;
	int ret = unw_getcontext(&context);
	if (ret) {
		UT_ERR("unw_getcontext: %s [%d]", unw_strerror(ret), ret);
		return;
	}

	unw_cursor_t cursor;
	ret = unw_init_local(&cursor, &context);
	if (ret) {
		UT_ERR("unw_init_local: %s [%d]", unw_strerror(ret), ret);
		return;
	}

	ret = unw_step(&cursor);

	char procname[PROCNAMELEN];
	unsigned i = 0;

	while (ret > 0) {
		ret = unw_get_proc_info(&cursor, &pip);
		if (ret) {
			UT_ERR("unw_get_proc_info: %s [%d]", unw_strerror(ret),
					ret);
			break;
		}

		unw_word_t off;
		ret = unw_get_proc_name(&cursor, procname, PROCNAMELEN, &off);
		if (ret && ret != -UNW_ENOMEM) {
			if (ret != -UNW_EUNSPEC) {
				UT_ERR("unw_get_proc_name: %s [%d]",
					unw_strerror(ret), ret);
			}

			strcpy(procname, "?");
		}

		void *ptr = (void *)(pip.start_ip + off);
		Dl_info dlinfo;
		const char *fname = "?";

		if (dladdr(ptr, &dlinfo) && dlinfo.dli_fname &&
				*dlinfo.dli_fname)
			fname = dlinfo.dli_fname;

		UT_ERR("%u: %s (%s%s+0x%lx) [%p]", i++, fname, procname,
				ret == -UNW_ENOMEM ? "..." : "", off, ptr);

		ret = unw_step(&cursor);
		if (ret < 0)
			UT_ERR("unw_step: %s [%d]", unw_strerror(ret), ret);
	}
}
Пример #7
0
Файл: ut.c Проект: AmesianX/nvml
/*
 * open_file_walk -- walk lut for any left-overs
 *
 * prints error if any found, increments Fd_errcount
 */
static void
open_file_walk(struct fd_lut *root)
{
	if (root) {
		open_file_walk(root->left);
		if (root->fdfile) {
			UT_ERR("open file missing: fd %d => \"%s\"",
			    root->fdnum, root->fdfile);
			Fd_errcount++;
		}
		open_file_walk(root->right);
	}
}
Пример #8
0
Файл: ut.c Проект: AmesianX/nvml
/*
 * open_file_remove -- find exact match & remove it from lut
 *
 * prints error if exact match not found, increments Fd_errcount
 */
static void
open_file_remove(struct fd_lut *root, int fdnum, const char *fdfile)
{
	if (root == NULL) {
		UT_ERR("unexpected open file: fd %d => \"%s\"", fdnum, fdfile);
		Fd_errcount++;
	} else if (root->fdnum == fdnum) {
		if (root->fdfile == NULL) {
			UT_ERR("open file dup: fd %d => \"%s\"", fdnum, fdfile);
			Fd_errcount++;
		} else if (strcmp(root->fdfile, fdfile) == 0) {
			/* found exact match */
			FREE(root->fdfile);
			root->fdfile = NULL;
		} else {
			UT_ERR("open file changed: fd %d was \"%s\" now \"%s\"",
			    fdnum, root->fdfile, fdfile);
			Fd_errcount++;
		}
	} else if (root->fdnum < fdnum)
		open_file_remove(root->left, fdnum, fdfile);
	else
		open_file_remove(root->right, fdnum, fdfile);
}
Пример #9
0
/*
 * cond_write_worker -- (internal) write data with cond variable
 */
static void *
cond_write_worker(void *arg)
{
	for (unsigned run = 0; run < WORKER_RUNS; run++) {
		if (pmemobj_mutex_lock(&Mock_pop, &Test_obj->mutex))
			return NULL;

		memset(Test_obj->data, (int)(uintptr_t)arg, DATA_SIZE);
		Test_obj->check_data = 1;
		if (pmemobj_cond_signal(&Mock_pop, &Test_obj->cond))
			UT_ERR("pmemobj_cond_signal");
		pmemobj_mutex_unlock(&Mock_pop, &Test_obj->mutex);
	}

	return NULL;
}
Пример #10
0
int
main(int argc, char *argv[])
{
	START(argc, argv, "remote_basic");

	if (argc != 2)
		UT_FATAL("usage: %s <file-to-be-checked>", argv[0]);

	const char *file = argv[1];

	if (access(file, F_OK) != 0)
		UT_FATAL("File '%s' does not exist", file);
	else
		UT_OUT("File '%s' exists", file);

	UT_OUT("An example of OUT message");

	UT_ERR("An example of ERR message");

	DONE(NULL);
}
Пример #11
0
/*
 * cond_check_worker -- (internal) check consistency with cond variable
 */
static void *
cond_check_worker(void *arg)
{
	for (unsigned run = 0; run < WORKER_RUNS; run++) {
		if (pmemobj_mutex_lock(&Mock_pop, &Test_obj->mutex))
			return NULL;

		while (Test_obj->check_data != 1) {
			if (pmemobj_cond_wait(&Mock_pop, &Test_obj->cond,
						&Test_obj->mutex))
				UT_ERR("pmemobj_cond_wait");
		}
		uint8_t val = Test_obj->data[0];
		for (int i = 1; i < DATA_SIZE; i++)
			UT_ASSERTeq(Test_obj->data[i], val);

		memset(Test_obj->data, 0, DATA_SIZE);
		pmemobj_mutex_unlock(&Mock_pop, &Test_obj->mutex);
	}

	return NULL;
}
Пример #12
0
int
main(int argc, char *argv[])
{
	int fd;
	size_t mapped_len;
	char *dest;
	char *dest1;
	char *ret;

	START(argc, argv, "pmem_memset");

	if (argc != 4)
		UT_FATAL("usage: %s file offset length", argv[0]);

	fd = OPEN(argv[1], O_RDWR);

	/* open a pmem file and memory map it */
	if ((dest = pmem_map_file(argv[1], 0, 0, 0, &mapped_len, NULL)) == NULL)
		UT_FATAL("!Could not mmap %s\n", argv[1]);

	int dest_off = atoi(argv[2]);
	size_t bytes = strtoul(argv[3], NULL, 0);

	char *buf = MALLOC(bytes);

	memset(dest, 0, bytes);
	util_persist_auto(util_fd_is_device_dax(fd), dest, bytes);
	dest1 = MALLOC(bytes);
	memset(dest1, 0, bytes);

	/*
	 * This is used to verify that the value of what a non persistent
	 * memset matches the outcome of the persistent memset. The
	 * persistent memset will match the file but may not be the
	 * correct or expected value.
	 */
	memset(dest1 + dest_off, 0x5A, bytes / 4);
	memset(dest1 + dest_off  + (bytes / 4), 0x46, bytes / 4);

	/* Test the corner cases */
	ret = pmem_memset_persist(dest + dest_off, 0x5A, 0);
	UT_ASSERTeq(ret, dest + dest_off);
	UT_ASSERTeq(*(char *)(dest + dest_off), 0);

	/*
	 * Do the actual memset with persistence.
	 */
	ret = pmem_memset_persist(dest + dest_off, 0x5A, bytes / 4);
	UT_ASSERTeq(ret, dest + dest_off);
	ret = pmem_memset_persist(dest + dest_off  + (bytes / 4),
					0x46, bytes / 4);
	UT_ASSERTeq(ret, dest + dest_off + (bytes / 4));

	if (memcmp(dest, dest1, bytes / 2))
		UT_ERR("%s: first %zu bytes do not match",
			argv[1], bytes / 2);

	LSEEK(fd, (off_t)0, SEEK_SET);
	if (READ(fd, buf, bytes / 2) == bytes / 2) {
		if (memcmp(buf, dest, bytes / 2))
			UT_ERR("%s: first %zu bytes do not match",
				argv[1], bytes / 2);
	}

	UT_ASSERTeq(pmem_unmap(dest, mapped_len), 0);

	FREE(dest1);
	FREE(buf);
	CLOSE(fd);

	DONE(NULL);
}
Пример #13
0
/*
 * do_memmove: Worker function for memmove.
 *
 * Always work within the boundary of bytes. Fill in 1/2 of the src
 * memory with the pattern we want to write. This allows us to check
 * that we did not overwrite anything we were not supposed to in the
 * dest. Use the non pmem version of the memset/memcpy commands
 * so as not to introduce any possible side affects.
 */
static void
do_memmove(int fd, char *dest, char *src, char *file_name, off_t dest_off,
	off_t src_off, off_t off, off_t bytes)
{
	void *ret;
	char *src1 = MALLOC(bytes);
	char *buf = MALLOC(bytes);
	char old;

	memset(buf, 0, bytes);
	memset(src1, 0, bytes);
	memset(src, 0x5A, bytes / 4);
	util_persist_auto(util_fd_is_device_dax(fd), src, bytes / 4);
	memset(src + bytes / 4, 0x54, bytes / 4);
	util_persist_auto(util_fd_is_device_dax(fd), src + bytes / 4,
			bytes / 4);

	/* dest == src */
	old = *(char *)(dest + dest_off);
	ret = pmem_memmove_persist(dest + dest_off, dest + dest_off, bytes / 2);
	UT_ASSERTeq(ret, dest + dest_off);
	UT_ASSERTeq(*(char *)(dest + dest_off), old);

	/* len == 0 */
	old = *(char *)(dest + dest_off);
	ret = pmem_memmove_persist(dest + dest_off, src + src_off, 0);
	UT_ASSERTeq(ret, dest + dest_off);
	UT_ASSERTeq(*(char *)(dest + dest_off), old);

	/*
	 * A side affect of the memmove call is that
	 * src contents will be changed in the case of overlapping
	 * addresses.
	 */
	memcpy(src1, src, bytes / 2);
	ret = pmem_memmove_persist(dest + dest_off, src + src_off, bytes / 2);
	UT_ASSERTeq(ret, dest + dest_off);

	/* memcmp will validate that what I expect in memory. */
	if (memcmp(src1 + src_off, dest + dest_off, bytes / 2))
		UT_ERR("%s: %zu bytes do not match with memcmp",
			file_name, bytes / 2);

	/*
	 * This is a special case. An overlapping dest means that
	 * src is a pointer to the file, and destination is src + dest_off +
	 * overlap. This is the basis for the comparison. The use of ERR
	 * here is deliberate. This will force a failure of the test but allow
	 * it to continue until its done. The idea is that allowing some
	 * to succeed and others to fail gives more information about what
	 * went wrong.
	 */
	if (dest > src && off != 0) {
		LSEEK(fd, (off_t)dest_off + off, SEEK_SET);
		if (READ(fd, buf, bytes / 2) == bytes / 2) {
			if (memcmp(src1 + src_off, buf, bytes / 2))
				UT_ERR("%s: first %zu bytes do not match",
					file_name, bytes / 2);
		}
	} else {
		LSEEK(fd, (off_t)dest_off, SEEK_SET);
		if (READ(fd, buf, bytes / 2) == bytes / 2) {
			if (memcmp(src1 + src_off, buf, bytes / 2))
				UT_ERR("%s: first %zu bytes do not match",
					file_name, bytes / 2);
		}
	}
	FREE(src1);
	FREE(buf);
}
Пример #14
0
int
main(int argc, char *argv[])
{
	int fd;
	char *dest;
	char *src;
	off_t dest_off = 0;
	off_t src_off = 0;
	uint64_t bytes = 0;
	int who = 0;
	off_t overlap = 0;
	size_t mapped_len;

	START(argc, argv, "pmem_memmove");

	fd = OPEN(argv[1], O_RDWR);

	if (argc < 3)
		USAGE();

	for (int arg = 2; arg < argc; arg++) {
		if (strchr("dsboS",
		    argv[arg][0]) == NULL || argv[arg][1] != ':')
			UT_FATAL("op must be d: or s: or b: or o: or S:");

		off_t val = strtoul(&argv[arg][2], NULL, 0);

		switch (argv[arg][0]) {
		case 'd':
			if (val <= 0)
				UT_FATAL("bad offset (%lu) with d: option",
						val);
			dest_off = val;
			break;

		case 's':
			if (val <= 0)
				UT_FATAL("bad offset (%lu) with s: option",
						val);
			src_off = val;
			break;

		case 'b':
			if (val <= 0)
				UT_FATAL("bad length (%lu) with b: option",
						val);
			bytes = val;
			break;

		case 'o':
			if (val != 1 && val != 2)
				UT_FATAL("bad val (%lu) with o: option",
						val);
			who = (int)val;
			break;

		case 'S':
			overlap = val;
			break;
		}
	}

	if (who == 0 && overlap != 0)
		USAGE();

	/* for overlap the src and dest must be created differently */
	if (who == 0) {
		/* src > dest */
		dest = pmem_map_file(argv[1], 0, 0, 0, &mapped_len, NULL);
		if (dest == NULL)
			UT_FATAL("!could not mmap dest file %s", argv[1]);

		src = MMAP(dest + mapped_len, mapped_len,
			PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS,
			-1, 0);
		/*
		 * Its very unlikely that src would not be > dest. pmem_map_file
		 * chooses the first unused address >= 1TB, large
		 * enough to hold the give range, and 1GB aligned. Log
		 * the error if the mapped addresses cannot be swapped
		 * but allow the test to continue.
		 */
		if (src <= dest) {
			swap_mappings(&dest, &src, mapped_len, fd);
			if (src <= dest)
				UT_ERR("cannot map files in memory order");
		}

		do_memmove(fd, dest, src, argv[1], dest_off, src_off,
			0, bytes);

		/* dest > src */
		swap_mappings(&dest, &src, mapped_len, fd);

		if (dest <= src)
			UT_ERR("cannot map files in memory order");

		do_memmove(fd, dest, src, argv[1], dest_off, src_off, 0,
			bytes);
		MUNMAP(dest, mapped_len);
		MUNMAP(src, mapped_len);
	} else if (who == 1) {
		/* src overlap with dest */
		dest = pmem_map_file(argv[1], 0, 0, 0, &mapped_len, NULL);
		if (dest == NULL)
			UT_FATAL("!Could not mmap %s: \n", argv[1]);

		src = dest + overlap;
		memset(dest, 0, bytes);
		util_persist_auto(util_fd_is_device_dax(fd), dest, bytes);
		do_memmove(fd, dest, src, argv[1], dest_off, src_off,
			overlap, bytes);
		MUNMAP(dest, mapped_len);
	} else {
		/* dest overlap with src */
		dest = pmem_map_file(argv[1], 0, 0, 0, &mapped_len, NULL);
		if (dest == NULL) {
			UT_FATAL("!Could not mmap %s: \n", argv[1]);
		}
		src = dest;
		dest = src + overlap;
		memset(src, 0, bytes);
		util_persist_auto(util_fd_is_device_dax(fd), src, bytes);
		do_memmove(fd, dest, src, argv[1], dest_off, src_off,
			overlap, bytes);
		MUNMAP(src, mapped_len);
	}

	CLOSE(fd);

	DONE(NULL);
}
Пример #15
0
int
main(int argc, char *argv[])
{
	START(argc, argv, "vmem_delete");

	VMEM *vmp;
	void *ptr;

	if (argc < 2)
		UT_FATAL("usage: %s op:h|f|m|c|r|a|s|d", argv[0]);

	/* allocate memory for function vmem_create_in_region() */
	void *mem_pool = MMAP_ANON_ALIGNED(VMEM_MIN_POOL, 4 << 20);

	vmp = vmem_create_in_region(mem_pool, VMEM_MIN_POOL);
	if (vmp == NULL)
		UT_FATAL("!vmem_create_in_region");

	ptr = vmem_malloc(vmp, sizeof(long long));
	if (ptr == NULL)
		UT_ERR("!vmem_malloc");
	vmem_delete(vmp);

	/* arrange to catch SEGV */
	struct sigaction v;
	sigemptyset(&v.sa_mask);
	v.sa_flags = 0;
	v.sa_handler = signal_handler;
	SIGACTION(SIGSEGV, &v, NULL);
	SIGACTION(SIGABRT, &v, NULL);
	SIGACTION(SIGILL, &v, NULL);

	/* go through all arguments one by one */
	for (int arg = 1; arg < argc; arg++) {
		/* Scan the character of each argument. */
		if (strchr("hfmcrasd", argv[arg][0]) == NULL ||
				argv[arg][1] != '\0')
			UT_FATAL("op must be one of: h, f, m, c, r, a, s, d");

		switch (argv[arg][0]) {
		case 'h':
			UT_OUT("Testing vmem_check...");
			if (!sigsetjmp(Jmp, 1)) {
				UT_OUT("\tvmem_check returned %i",
							vmem_check(vmp));
			}
			break;

		case 'f':
			UT_OUT("Testing vmem_free...");
			if (!sigsetjmp(Jmp, 1)) {
				vmem_free(vmp, ptr);
				UT_OUT("\tvmem_free succeeded");
			}
			break;

		case 'm':
			UT_OUT("Testing vmem_malloc...");
			if (!sigsetjmp(Jmp, 1)) {
				ptr = vmem_malloc(vmp, sizeof(long long));
				if (ptr != NULL)
					UT_OUT("\tvmem_malloc succeeded");
				else
					UT_OUT("\tvmem_malloc returned NULL");
			}
			break;

		case 'c':
			UT_OUT("Testing vmem_calloc...");
			if (!sigsetjmp(Jmp, 1)) {
				ptr = vmem_calloc(vmp, 10, sizeof(int));
				if (ptr != NULL)
					UT_OUT("\tvmem_calloc succeeded");
				else
					UT_OUT("\tvmem_calloc returned NULL");
			}
			break;

		case 'r':
			UT_OUT("Testing vmem_realloc...");
			if (!sigsetjmp(Jmp, 1)) {
				ptr = vmem_realloc(vmp, ptr, 128);
				if (ptr != NULL)
					UT_OUT("\tvmem_realloc succeeded");
				else
					UT_OUT("\tvmem_realloc returned NULL");
			}
			break;

		case 'a':
			UT_OUT("Testing vmem_aligned_alloc...");
			if (!sigsetjmp(Jmp, 1)) {
				ptr = vmem_aligned_alloc(vmp, 128, 128);
				if (ptr != NULL)
					UT_OUT("\tvmem_aligned_alloc "
						"succeeded");
				else
					UT_OUT("\tvmem_aligned_alloc"
							" returned NULL");
			}
			break;

		case 's':
			UT_OUT("Testing vmem_strdup...");
			if (!sigsetjmp(Jmp, 1)) {
				ptr = vmem_strdup(vmp, "Test string");
				if (ptr != NULL)
					UT_OUT("\tvmem_strdup succeeded");
				else
					UT_OUT("\tvmem_strdup returned NULL");
			}
			break;

		case 'd':
			UT_OUT("Testing vmem_delete...");
			if (!sigsetjmp(Jmp, 1)) {
				vmem_delete(vmp);
				if (errno != 0)
					UT_OUT("\tvmem_delete failed: %s",
						vmem_errormsg());
				else
					UT_OUT("\tvmem_delete succeeded");
			}
			break;
		}
	}

	DONE(NULL);
}