Esempio n. 1
0
/*
 * check_pool -- check if remote pool contains specified random sequence
 */
static int
check_pool(const struct test_case *tc, int argc, char *argv[])
{
	if (argc < 3)
		UT_FATAL("usage: fill_pool <pool set> <seed> <size>");

	char *pool_set = argv[0];
	srand(atoi(argv[1]));

	int ret;

	size_t size;
	ret = util_parse_size(argv[2], &size);

	struct pool_set *set;
	ret = util_pool_open_nocheck(&set, pool_set, 0);
	UT_ASSERTeq(ret, 0);

	uint8_t *data = set->replica[0]->part[0].addr;
	for (size_t i = 0; i < size; i++) {
		uint8_t r = rand();
		UT_ASSERTeq(data[POOL_HDR_SIZE + i], r);
	}

	util_poolset_close(set, 0);

	return 3;
}
Esempio n. 2
0
File: pool.c Progetto: krzycz/nvml
/*
 * pool_set_file_open -- (internal) opens pool set file or regular file
 */
static struct pool_set_file *
pool_set_file_open(const char *fname, struct pool_params *params, int rdonly)
{
	LOG(3, NULL);

	struct pool_set_file *file = calloc(1, sizeof(*file));
	if (!file)
		return NULL;

	file->fname = strdup(fname);
	if (!file->fname)
		goto err;

	const char *path = file->fname;

	if (params->type != POOL_TYPE_BTT) {
		int ret = util_poolset_create_set(&file->poolset, path,
			0, 0, true);
		if (ret < 0) {
			LOG(2, "cannot open pool set -- '%s'", path);
			goto err_free_fname;
		}
		unsigned flags = (rdonly ? POOL_OPEN_COW : 0) |
					POOL_OPEN_IGNORE_BAD_BLOCKS;
		if (util_pool_open_nocheck(file->poolset, flags))
			goto err_free_fname;

		file->size = file->poolset->poolsize;

		/* get modification time from the first part of first replica */
		path = file->poolset->replica[0]->part[0].path;
		file->addr = file->poolset->replica[0]->part[0].addr;
	} else {
		int oflag = rdonly ? O_RDONLY : O_RDWR;
		file->fd = util_file_open(fname, NULL, 0, oflag);
		file->size = params->size;
	}

	os_stat_t buf;
	if (os_stat(path, &buf)) {
		ERR("%s", path);
		goto err_close_poolset;
	}

	file->mtime = buf.st_mtime;
	file->mode = buf.st_mode;
	return file;

err_close_poolset:
	if (params->type != POOL_TYPE_BTT)
		util_poolset_close(file->poolset, DO_NOT_DELETE_PARTS);
	else if (file->fd != -1)
		os_close(file->fd);
err_free_fname:
	free(file->fname);
err:
	free(file);
	return NULL;
}
Esempio n. 3
0
/*
 * fill_pool -- fill remote pool with specified random sequence
 */
static int
fill_pool(const struct test_case *tc, int argc, char *argv[])
{
	if (argc < 2)
		UT_FATAL("usage: fill_pool <pool set> <seed>");

	char *pool_set = argv[0];
	srand(atoi(argv[1]));

	int ret;

	struct pool_set *set;
	ret = util_pool_open_nocheck(&set, pool_set, 0);
	UT_ASSERTeq(ret, 0);

	uint8_t *data = set->replica[0]->part[0].addr;
	for (size_t i = POOL_HDR_SIZE; i < set->poolsize; i++)
		data[i] = rand();

	util_poolset_close(set, 0);

	return 2;
}
Esempio n. 4
0
File: pool.c Progetto: mslusarz/nvml
/*
 * pool_parse_params -- parse pool type, file size and block size
 */
static int
pool_params_parse(const PMEMpoolcheck *ppc, struct pool_params *params,
	int check)
{
	LOG(3, NULL);
	int is_btt = ppc->args.pool_type == PMEMPOOL_POOL_TYPE_BTT;

	params->type = POOL_TYPE_UNKNOWN;
	params->is_poolset = util_is_poolset_file(ppc->path) == 1;

	int fd = util_file_open(ppc->path, NULL, 0, O_RDONLY);
	if (fd < 0)
		return -1;

	int ret = 0;

	util_stat_t stat_buf;
	ret = util_fstat(fd, &stat_buf);
	if (ret)
		goto out_close;

	ASSERT(stat_buf.st_size >= 0);

	params->mode = stat_buf.st_mode;

	struct pool_set *set;
	void *addr;
	if (params->is_poolset) {
		/*
		 * Need to close the poolset because it will be opened with
		 * flock in the following instructions.
		 */
		close(fd);
		fd = -1;

		if (check) {
			if (pool_set_map(ppc->path, &set, 0))
				return -1;
		} else {
			ret = util_poolset_create_set(&set, ppc->path, 0, 0);
			if (ret < 0) {
				LOG(2, "cannot open pool set -- '%s'",
					ppc->path);
				return -1;
			}
			if (set->remote) {
				ERR("poolsets with remote replicas are not "
					"supported");
				return -1;
			}
			if (util_pool_open_nocheck(set, 0))
				return -1;
		}

		params->size = set->poolsize;
		addr = set->replica[0]->part[0].addr;

		/*
		 * XXX mprotect for device dax with length not aligned to its
		 * page granularity causes SIGBUS on the next page fault.
		 * The length argument of this call should be changed to
		 * set->poolsize once the kernel issue is solved.
		 */
		if (mprotect(addr, set->replica[0]->repsize,
			PROT_READ) < 0) {
			ERR("!mprotect");
			goto out_unmap;
		}
		params->is_device_dax = set->replica[0]->part[0].is_dax;
	} else if (is_btt) {
		params->size = (size_t)stat_buf.st_size;
#ifndef _WIN32
		if (params->mode & S_IFBLK)
			if (ioctl(fd, BLKGETSIZE64, &params->size)) {
				ERR("!ioctl");
				goto out_close;
			}
#endif
		addr = NULL;
	} else {
		ssize_t s = util_file_get_size(ppc->path);
		if (s < 0) {
			ret = -1;
			goto out_close;
		}
		params->size = (size_t)s;
		addr = mmap(NULL, (uint64_t)params->size, PROT_READ,
			MAP_PRIVATE, fd, 0);
		if (addr == MAP_FAILED) {
			ret = -1;
			goto out_close;
		}
		params->is_device_dax = util_file_is_device_dax(ppc->path);
	}

	/* stop processing for BTT device */
	if (is_btt) {
		params->type = POOL_TYPE_BTT;
		params->is_part = false;
		goto out_close;
	}

	struct pool_hdr hdr;
	memcpy(&hdr, addr, sizeof(hdr));
	util_convert2h_hdr_nocheck(&hdr);
	pool_params_from_header(params, &hdr);

	if (ppc->args.pool_type != PMEMPOOL_POOL_TYPE_DETECT) {
		enum pool_type declared_type =
			pmempool_check_type_to_pool_type(ppc->args.pool_type);
		if ((params->type & ~declared_type) != 0) {
			ERR("declared pool type does not match");
			ret = 1;
			goto out_unmap;
		}
	}

	if (params->type == POOL_TYPE_BLK) {
		struct pmemblk pbp;
		memcpy(&pbp, addr, sizeof(pbp));
		params->blk.bsize = le32toh(pbp.bsize);
	} else if (params->type == POOL_TYPE_OBJ) {
		struct pmemobjpool pop;
		memcpy(&pop, addr, sizeof(pop));
		memcpy(params->obj.layout, pop.layout,
			PMEMOBJ_MAX_LAYOUT);
	}

out_unmap:
	if (params->is_poolset) {
		ASSERTeq(fd, -1);
		ASSERTne(addr, NULL);
		util_poolset_close(set, 0);
	} else if (!is_btt) {
		ASSERTne(fd, -1);
		ASSERTne(addr, NULL);
		munmap(addr, params->size);
	}
out_close:
	if (fd != -1)
		close(fd);
	return ret;
}