示例#1
0
文件: info.c 项目: tomaszkapela/nvml
/*
 * pmempool_info_part -- (internal) print info about poolset part
 */
static int
pmempool_info_part(struct pmem_info *pip, unsigned repn, unsigned partn, int v)
{
	/* get path of the part file */
	const char *path = NULL;
	if (repn != UNDEF_REPLICA && partn != UNDEF_PART) {
		outv(v, "part %u:\n", partn);
		struct pool_set_part *part =
			&pip->pfile->poolset->replica[repn]->part[partn];
		path = part->path;
	} else {
		outv(v, "Part file:\n");
		path = pip->file_name;
	}
	outv_field(v, "path", "%s", path);

	/* get type of the part file */
	int is_dev_dax = util_file_is_device_dax(path);
	const char *type_str = is_dev_dax ? "device dax" : "regular file";
	outv_field(v, "type", "%s", type_str);

	/* get size of the part file */
	ssize_t size = util_file_get_size(path);
	if (size < 0) {
		outv_err("couldn't get size of %s", path);
		return -1;
	}
	outv_field(v, "size", "%s", out_get_size_str((size_t)size,
			pip->args.human));

	return 0;
}
示例#2
0
文件: file.c 项目: ChandKV/nvml
/*
 * util_file_pread -- reads from a file with an offset
 */
ssize_t
util_file_pread(const char *path, void *buffer, size_t size,
	off_t offset)
{
	if (!util_file_is_device_dax(path)) {
		int fd = util_file_open(path, NULL, 0, O_RDONLY);
		if (fd < 0)
			return -1;

		ssize_t read_len = pread(fd, buffer, size, offset);
		int olderrno = errno;
		(void) close(fd);
		errno = olderrno;
		return read_len;
	}

	ssize_t file_size = util_file_get_size(path);
	if (file_size < 0)
		return -1;

	size_t max_size = (size_t)(file_size - offset);
	if (size > max_size) {
		LOG(1, "Requested size of read goes beyond the mapped memory");
		size = max_size;
	}

	void *addr = util_file_map_whole(path);
	if (addr == NULL)
		return -1;

	memcpy(buffer, ADDR_SUM(addr, offset), size);
	util_unmap(addr, (size_t)file_size);
	return (ssize_t)size;
}
示例#3
0
文件: file.c 项目: mslusarz/nvml
/*
 * util_unlink -- unlinks a file or zeroes a device dax
 */
int
util_unlink(const char *path)
{
	if (util_file_is_device_dax(path)) {
		return util_file_zero_whole(path);
	} else {
		return unlink(path);
	}
}
示例#4
0
文件: file.c 项目: ChandKV/nvml
/*
 * util_unlink -- unlinks a file or zeroes a device dax
 */
int
util_unlink(const char *path)
{
	if (util_file_is_device_dax(path)) {
		return util_file_zero_whole(path);
	} else {
/*
 * On Windows we can not unlink Read-Only files
 */
#ifdef _WIN32
		_chmod(path, _S_IREAD | _S_IWRITE);
#endif
		return unlink(path);
	}
}
示例#5
0
文件: pmemdetect.c 项目: ChandKV/nvml
/*
 * is_dev_dax -- checks if given path points to device dax
 */
static int
is_dev_dax(const char *path)
{
	if (!util_file_is_device_dax(path)) {
		printf("%s -- not device dax\n", path);
		return 0;
	}

	if (access(path, W_OK|R_OK)) {
		printf("%s -- permission denied\n", path);
		return -1;
	}

	return 1;
}
示例#6
0
文件: file.c 项目: ChandKV/nvml
/*
 * util_file_get_size -- returns size of a file
 */
ssize_t
util_file_get_size(const char *path)
{
#ifndef _WIN32
	if (util_file_is_device_dax(path)) {
		return device_dax_size(path);
	}
#endif

	util_stat_t stbuf;
	if (util_stat(path, &stbuf) < 0) {
		ERR("!fstat %s", path);
		return -1;
	}

	return stbuf.st_size;
}
示例#7
0
文件: pool.c 项目: 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;
}
示例#8
0
/*
 * pobj_init - common part of the benchmark initialization functions.
 * Parses command line arguments, set variables and creates persistent pools.
 */
static int
pobj_init(struct benchmark *bench, struct benchmark_args *args)
{
	unsigned i = 0;
	size_t psize;
	size_t n_objs;

	assert(bench != nullptr);
	assert(args != nullptr);

	auto *bench_priv =
		(struct pobj_bench *)malloc(sizeof(struct pobj_bench));
	if (bench_priv == nullptr) {
		perror("malloc");
		return -1;
	}
	assert(args->opts != nullptr);

	bench_priv->args_priv = (struct pobj_args *)args->opts;
	bench_priv->args_priv->obj_size = args->dsize;
	bench_priv->args_priv->range =
		bench_priv->args_priv->min_size > 0 ? true : false;
	bench_priv->n_pools =
		!bench_priv->args_priv->one_pool ? args->n_threads : 1;
	bench_priv->pool = bench_priv->n_pools > 1 ? diff_num : one_num;
	bench_priv->obj = !bench_priv->args_priv->one_obj ? diff_num : one_num;

	if ((args->is_poolset || util_file_is_device_dax(args->fname)) &&
	    bench_priv->n_pools > 1) {
		fprintf(stderr,
			"cannot use poolset nor device dax for multiple pools,"
			" please use -P|--one-pool option instead");
		goto free_bench_priv;
	}
	/*
	 * Multiplication by FACTOR prevents from out of memory error
	 * as the actual size of the allocated persistent objects
	 * is always larger than requested.
	 */
	n_objs = bench_priv->args_priv->n_objs;
	if (bench_priv->n_pools == 1)
		n_objs *= args->n_threads;
	psize = n_objs * args->dsize * args->n_threads * FACTOR;
	if (psize < PMEMOBJ_MIN_POOL)
		psize = PMEMOBJ_MIN_POOL;

	/* assign type_number determining function */
	bench_priv->type_mode =
		parse_type_mode(bench_priv->args_priv->type_num);
	switch (bench_priv->type_mode) {
		case MAX_TYPE_MODE:
			fprintf(stderr, "unknown type mode");
			goto free_bench_priv;
		case TYPE_MODE_RAND:
			if (random_types(bench_priv, args))
				goto free_bench_priv;
			break;
		default:
			bench_priv->random_types = nullptr;
	}
	bench_priv->fn_type_num = type_mode_func[bench_priv->type_mode];

	/* assign size determining function */
	bench_priv->fn_size =
		bench_priv->args_priv->range ? range_size : static_size;
	bench_priv->rand_sizes = nullptr;
	if (bench_priv->args_priv->range) {
		if (bench_priv->args_priv->min_size > args->dsize) {
			fprintf(stderr, "Invalid allocation size");
			goto free_random_types;
		}
		bench_priv->rand_sizes =
			rand_sizes(bench_priv->args_priv->min_size,
				   bench_priv->args_priv->obj_size,
				   bench_priv->args_priv->n_objs);
		if (bench_priv->rand_sizes == nullptr)
			goto free_random_types;
	}

	assert(bench_priv->n_pools > 0);
	bench_priv->pop = (PMEMobjpool **)calloc(bench_priv->n_pools,
						 sizeof(PMEMobjpool *));
	if (bench_priv->pop == nullptr) {
		perror("calloc");
		goto free_random_sizes;
	}

	bench_priv->sets = (const char **)calloc(bench_priv->n_pools,
						 sizeof(const char *));
	if (bench_priv->sets == nullptr) {
		perror("calloc");
		goto free_pop;
	}
	if (bench_priv->n_pools > 1) {
		assert(!args->is_poolset);
		if (util_file_mkdir(args->fname, DIR_MODE) != 0) {
			fprintf(stderr, "cannot create directory\n");
			goto free_sets;
		}
		size_t path_len = (strlen(PART_NAME) + strlen(args->fname)) +
			MAX_DIGITS + 1;
		for (i = 0; i < bench_priv->n_pools; i++) {
			bench_priv->sets[i] =
				(char *)malloc(path_len * sizeof(char));
			if (bench_priv->sets[i] == nullptr) {
				perror("malloc");
				goto free_sets;
			}
			int ret =
				snprintf((char *)bench_priv->sets[i], path_len,
					 "%s%s%02x", args->fname, PART_NAME, i);
			if (ret < 0 || ret >= (int)path_len) {
				perror("snprintf");
				goto free_sets;
			}
			bench_priv->pop[i] =
				pmemobj_create(bench_priv->sets[i], LAYOUT_NAME,
					       psize, FILE_MODE);
			if (bench_priv->pop[i] == nullptr) {
				perror(pmemobj_errormsg());
				goto free_sets;
			}
		}
	} else {
		if (args->is_poolset || util_file_is_device_dax(args->fname)) {
			if (args->fsize < psize) {
				fprintf(stderr, "file size too large\n");
				goto free_pools;
			}
			psize = 0;
		}
		bench_priv->sets[0] = args->fname;
		bench_priv->pop[0] = pmemobj_create(
			bench_priv->sets[0], LAYOUT_NAME, psize, FILE_MODE);
		if (bench_priv->pop[0] == nullptr) {
			perror(pmemobj_errormsg());
			goto free_pools;
		}
	}
	pmembench_set_priv(bench, bench_priv);

	return 0;
free_sets:
	for (; i > 0; i--) {
		pmemobj_close(bench_priv->pop[i - 1]);
		free((char *)bench_priv->sets[i - 1]);
	}
free_pools:
	free(bench_priv->sets);
free_pop:
	free(bench_priv->pop);
free_random_sizes:
	free(bench_priv->rand_sizes);
free_random_types:
	free(bench_priv->random_types);
free_bench_priv:
	free(bench_priv);

	return -1;
}