Beispiel #1
0
/*
 * update_replica_header -- (internal) update field values in the first header
 *                          in the replica
 */
static void
update_replica_header(struct pool_set *set, unsigned repn)
{
	LOG(3, "set %p, repn %u", set, repn);
	struct pool_replica *rep = REP(set, repn);
	struct pool_set_part *part = PART(REP(set, repn), 0);
	struct pool_hdr *hdr = (struct pool_hdr *)part->hdr;
	if (set->options & OPTION_SINGLEHDR) {
		hdr->incompat_features |= POOL_FEAT_SINGLEHDR;
		memcpy(hdr->next_part_uuid, hdr->uuid, POOL_HDR_UUID_LEN);
		memcpy(hdr->prev_part_uuid, hdr->uuid, POOL_HDR_UUID_LEN);
	} else {
		hdr->incompat_features &= (uint32_t)(~POOL_FEAT_SINGLEHDR);

	}
	util_checksum(hdr, sizeof(*hdr), &hdr->checksum, 1,
		POOL_HDR_CSUM_END_OFF);
	util_persist_auto(rep->is_pmem, hdr, sizeof(*hdr));
}
Beispiel #2
0
/*
 * pool_write -- write to pool set file or regular file
 *
 * 'buff' has to be a buffer at least 'nbytes' long
 * 'off' is an offset from the beginning of the pool
 */
int
pool_write(struct pool_data *pool, const void *buff, size_t nbytes,
	uint64_t off)
{
	if (off + nbytes > pool->set_file->size)
		return -1;

	if (pool->params.type != POOL_TYPE_BTT) {
		memcpy((char *)pool->set_file->addr + off, buff, nbytes);
		util_persist_auto(pool->params.is_dev_dax,
				(char *)pool->set_file->addr + off, nbytes);
	} else {
		if (pool_btt_lseek(pool, (off_t)off, SEEK_SET) == -1)
			return -1;
		if ((size_t)pool_btt_write(pool, buff, nbytes) != nbytes)
			return -1;
	}

	return 0;
}
Beispiel #3
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);
}
Beispiel #4
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);
}
Beispiel #5
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);
}