예제 #1
0
파일: set.c 프로젝트: bgbhpe/nvml
/*
 * util_poolset_foreach_part -- walk through all poolset file parts
 *
 * Stops processing if callback returns non-zero value.
 * The value returned by callback is returned to the caller.
 *
 * Return value:
 *  0 - all part files have been processed
 * -1 - parsing poolset file error
 */
int
util_poolset_foreach_part(const char *path,
	int (*cb)(const char *part_file, void *arg), void *arg)
{
	int fd = open(path, O_RDONLY);
	if (fd < 0)
		return -1;

	struct pool_set *set;
	int ret = util_poolset_parse(path, fd, &set);
	if (ret)
		goto err_close;

	for (unsigned r = 0; r < set->nreplicas; r++) {
		for (unsigned p = 0; p < set->replica[r]->nparts; p++) {
			const char *part_file = set->replica[r]->part[p].path;
			ret = cb(part_file, arg);
			if (ret)
				goto out;
		}
	}
out:
	util_poolset_free(set);
err_close:
	close(fd);
	return ret;
}
예제 #2
0
int
main(int argc, char *argv[])
{
	START(argc, argv, "util_poolset_parse");

	out_init(LOG_PREFIX, LOG_LEVEL_VAR, LOG_FILE_VAR,
			MAJOR_VERSION, MINOR_VERSION);

	if (argc < 2)
		FATAL("usage: %s set-file-name ...", argv[0]);

	struct pool_set *set;
	int fd;

	for (int i = 1; i < argc; i++) {
		const char *path = argv[i];

		fd = OPEN(path, O_RDWR);

		int ret = util_poolset_parse(path, fd, &set);
		if (ret == 0)
			util_poolset_free(set);

		CLOSE(fd);
	}

	out_fini();

	DONE(NULL);
}
예제 #3
0
파일: set.c 프로젝트: jebtang/nvml
/*
 * util_poolset_open -- (internal) open memory pool set
 *
 * On success returns 0 and a pointer to a newly allocated structure
 * containing the info of all the parts of the pool set and replicas.
 */
static int
util_poolset_open(struct pool_set **setp, const char *path, size_t minsize)
{
	LOG(3, "setp %p path %s minsize %zu", setp, path, minsize);

	int oerrno;
	int ret = 0;
	int fd;
	size_t size = 0;

	/* do not check minsize */
	if ((fd = util_file_open(path, &size, 0, O_RDWR)) == -1)
		return -1;

	char signature[POOLSET_HDR_SIG_LEN];
	ret = read(fd, signature, POOLSET_HDR_SIG_LEN);
	if (ret < 0) {
		ERR("!read %d", fd);
		goto err;
	}

	if (ret < POOLSET_HDR_SIG_LEN ||
	    strncmp(signature, POOLSET_HDR_SIG, POOLSET_HDR_SIG_LEN)) {
		LOG(4, "not a pool set header");

		if (size < minsize) {
			ERR("size %zu smaller than %zu", size, minsize);
			errno = EINVAL;
			ret = -1;
			goto err;
		}

		*setp = util_poolset_single(path, size, fd, 0);
		if (*setp == NULL) {
			ret = -1;
			goto err;
		}

		/* do not close the file */
		return 0;
	}

	ret = util_poolset_parse(path, fd, setp);
	if (ret != 0)
		goto err;

	ret = util_poolset_files(*setp, minsize, 0);
	if (ret != 0)
		util_poolset_close(*setp, 0);

err:
	oerrno = errno;
	(void) close(fd);
	errno = oerrno;
	return ret;
}
예제 #4
0
/*
 * pmempool_sync -- synchronize replicas within a poolset
 */
int
pmempool_sync(const char *poolset, unsigned flags)
{
	ASSERTne(poolset, NULL);

	/* check if poolset has correct signature */
	if (util_is_poolset_file(poolset) != 1) {
		ERR("file is not a poolset file");
		goto err;
	}

	/* open poolset file */
	int fd = util_file_open(poolset, NULL, 0, O_RDONLY);
	if (fd < 0) {
		ERR("cannot open a poolset file");
		goto err;
	}

	/* fill up pool_set structure */
	struct pool_set *set = NULL;
	if (util_poolset_parse(&set, poolset, fd)) {
		ERR("parsing input poolset failed");
		goto err_close_file;
	}
	if (set->remote) {
		if (util_remote_load()) {
			ERR("remote replication not available");
			goto err_close_file;
		}
	}

	/* sync all replicas */
	if (sync_replica(set, flags)) {
		LOG(1, "Synchronization failed");
		goto err_close_all;
	}

	util_poolset_close(set, 0);
	close(fd);
	return 0;

err_close_all:
	util_poolset_close(set, 0);

err_close_file:
	close(fd);

err:
	if (errno == 0)
		errno = EINVAL;

	return -1;
}
예제 #5
0
파일: set.c 프로젝트: bgbhpe/nvml
/*
 * util_poolset_read -- read memory pool set file
 *
 * On success returns 0 and a pointer to a newly allocated structure
 * containing the info of all the parts of the pool set and replicas.
 */
int
util_poolset_read(struct pool_set **setp, const char *path)
{
	LOG(3, "setp %p path %s", setp, path);

	int oerrno;
	int ret = 0;
	int fd;

	if ((fd = open(path, O_RDONLY)) < 0)
		return -1;

	ret = util_poolset_parse(path, fd, setp);

	oerrno = errno;
	(void) close(fd);
	errno = oerrno;
	return ret;
}
예제 #6
0
파일: set.c 프로젝트: bgbhpe/nvml
/*
 * util_poolset_size -- get size of poolset, returns 0 on error
 */
size_t
util_poolset_size(const char *path)
{
	int fd = open(path, O_RDONLY);
	if (fd < 0)
		return 0;

	size_t size = 0;
	struct pool_set *set;
	if (util_poolset_parse(path, fd, &set))
		goto err_close;

	size = set->poolsize;

	util_poolset_free(set);
err_close:
	close(fd);
	return size;
}
예제 #7
0
파일: pool.c 프로젝트: mslusarz/nvml
/*
 * pool_set_parse -- parse poolset file
 */
int
pool_set_parse(struct pool_set **setp, const char *path)
{
	LOG(3, "setp %p path %s", setp, path);

	int fd = open(path, O_RDONLY);
	int ret = 0;

	if (fd < 0)
		return 1;

	if (util_poolset_parse(setp, path, fd)) {
		ret = 1;
		goto err_close;
	}

err_close:
	close(fd);
	return ret;
}
예제 #8
0
파일: replica.c 프로젝트: ChandKV/nvml
/*
 * pmempool_transform -- alter poolset structure
 */
int
pmempool_transform(const char *poolset_src,
		const char *poolset_dst, unsigned flags)
{
	LOG(3, "poolset_src %s, poolset_dst %s, flags %u", poolset_src,
			poolset_dst, flags);
	ASSERTne(poolset_src, NULL);
	ASSERTne(poolset_dst, NULL);

	/* check if the source poolset has correct signature */
	if (util_is_poolset_file(poolset_src) != 1) {
		ERR("source file is not a poolset file");
		goto err;
	}

	/* check if the destination poolset has correct signature */
	if (util_is_poolset_file(poolset_dst) != 1) {
		ERR("destination file is not a poolset file");
		goto err;
	}

	/* check if flags are supported */
	if (check_flags_transform(flags)) {
		ERR("unsupported flags");
		errno = EINVAL;
		goto err;
	}

	/* open the source poolset file */
	int fd_in = util_file_open(poolset_src, NULL, 0, O_RDONLY);
	if (fd_in < 0) {
		ERR("cannot open source poolset file");
		goto err;
	}

	/* parse the source poolset file */
	struct pool_set *set_in = NULL;
	if (util_poolset_parse(&set_in, poolset_src, fd_in)) {
		ERR("parsing source poolset failed");
		close(fd_in);
		goto err;
	}
	close(fd_in);

	/* open the destination poolset file */
	int fd_out = util_file_open(poolset_dst, NULL, 0, O_RDONLY);
	if (fd_out < 0) {
		ERR("cannot open destination poolset file");
		goto err;
	}

	int del = 0;

	/* parse the destination poolset file */
	struct pool_set *set_out = NULL;
	if (util_poolset_parse(&set_out, poolset_dst, fd_out)) {
		ERR("parsing destination poolset failed");
		close(fd_out);
		goto err_free_poolin;
	}
	close(fd_out);

	/* check if the source poolset is of a correct type */
	if (pool_set_type(set_in) != POOL_TYPE_OBJ) {
		ERR("source poolset is of a wrong type");
		goto err_free_poolout;
	}

	/* check if the source poolset is healthy */
	struct poolset_health_status *set_in_hs = NULL;
	if (replica_check_poolset_health(set_in, &set_in_hs, flags)) {
		ERR("source poolset health check failed");
		goto err_free_poolout;
	}

	if (!replica_is_poolset_healthy(set_in_hs)) {
		ERR("source poolset is broken");
		replica_free_poolset_health_status(set_in_hs);
		goto err_free_poolout;
	}

	replica_free_poolset_health_status(set_in_hs);

	del = !is_dry_run(flags);

	/* transform poolset */
	if (replica_transform(set_in, set_out, flags)) {
		ERR("transformation failed");
		goto err_free_poolout;
	}

	util_poolset_close(set_in, 0);
	util_poolset_close(set_out, 0);
	return 0;

err_free_poolout:
	util_poolset_close(set_out, del);

err_free_poolin:
	util_poolset_close(set_in, 0);

err:
	if (errno == 0)
		errno = EINVAL;

	return -1;
}
예제 #9
0
파일: replica.c 프로젝트: wojtuss/nvml
static inline
#endif
int
pmempool_transformU(const char *poolset_src,
		const char *poolset_dst, unsigned flags)
{
	LOG(3, "poolset_src %s, poolset_dst %s, flags %u", poolset_src,
			poolset_dst, flags);
	ASSERTne(poolset_src, NULL);
	ASSERTne(poolset_dst, NULL);

	/* check if the source poolset has correct signature */
	if (util_is_poolset_file(poolset_src) != 1) {
		ERR("source file is not a poolset file");
		goto err;
	}

	/* check if the destination poolset has correct signature */
	if (util_is_poolset_file(poolset_dst) != 1) {
		ERR("destination file is not a poolset file");
		goto err;
	}

	/* check if flags are supported */
	if (check_flags_transform(flags)) {
		ERR("unsupported flags");
		errno = EINVAL;
		goto err;
	}

	/* open the source poolset file */
	int fd_in = util_file_open(poolset_src, NULL, 0, O_RDONLY);
	if (fd_in < 0) {
		ERR("cannot open source poolset file");
		goto err;
	}

	/* parse the source poolset file */
	struct pool_set *set_in = NULL;
	if (util_poolset_parse(&set_in, poolset_src, fd_in)) {
		ERR("parsing source poolset failed");
		os_close(fd_in);
		goto err;
	}
	os_close(fd_in);

	/* open the destination poolset file */
	int fd_out = util_file_open(poolset_dst, NULL, 0, O_RDONLY);
	if (fd_out < 0) {
		ERR("cannot open destination poolset file");
		goto err;
	}

	enum del_parts_mode del = DO_NOT_DELETE_PARTS;

	/* parse the destination poolset file */
	struct pool_set *set_out = NULL;
	if (util_poolset_parse(&set_out, poolset_dst, fd_out)) {
		ERR("parsing destination poolset failed");
		os_close(fd_out);
		goto err_free_poolin;
	}
	os_close(fd_out);

	/* check if the source poolset is of a correct type */
	if (pool_set_type(set_in) != POOL_TYPE_OBJ) {
		ERR("source poolset is of a wrong type");
		goto err_free_poolout;
	}

	/* load remote library if needed */
	if (set_in->remote && util_remote_load()) {
		ERR("remote replication not available");
		goto err_free_poolout;
	}
	if (set_out->remote && util_remote_load()) {
		ERR("remote replication not available");
		goto err_free_poolout;
	}

	del = is_dry_run(flags) ? DO_NOT_DELETE_PARTS : DELETE_CREATED_PARTS;

	/* transform poolset */
	if (replica_transform(set_in, set_out, flags)) {
		ERR("transformation failed");
		goto err_free_poolout;
	}

	util_poolset_close(set_in, DO_NOT_DELETE_PARTS);
	util_poolset_close(set_out, DO_NOT_DELETE_PARTS);
	return 0;

err_free_poolout:
	util_poolset_close(set_out, del);

err_free_poolin:
	util_poolset_close(set_in, DO_NOT_DELETE_PARTS);

err:
	if (errno == 0)
		errno = EINVAL;

	return -1;
}
예제 #10
0
파일: replica.c 프로젝트: wojtuss/nvml
static inline
#endif
int
pmempool_syncU(const char *poolset, unsigned flags)
{
	LOG(3, "poolset %s, flags %u", poolset, flags);
	ASSERTne(poolset, NULL);

	/* check if poolset has correct signature */
	if (util_is_poolset_file(poolset) != 1) {
		ERR("file is not a poolset file");
		goto err;
	}

	/* check if flags are supported */
	if (check_flags_sync(flags)) {
		ERR("unsupported flags");
		errno = EINVAL;
		goto err;
	}

	/* open poolset file */
	int fd = util_file_open(poolset, NULL, 0, O_RDONLY);
	if (fd < 0) {
		ERR("cannot open a poolset file");
		goto err;
	}

	/* fill up pool_set structure */
	struct pool_set *set = NULL;
	if (util_poolset_parse(&set, poolset, fd)) {
		ERR("parsing input poolset failed");
		goto err_close_file;
	}

	if (set->remote && util_remote_load()) {
		ERR("remote replication not available");
		goto err_close_file;
	}

	/* sync all replicas */
	if (replica_sync(set, NULL, flags)) {
		LOG(1, "synchronization failed");
		goto err_close_all;
	}

	util_poolset_close(set, DO_NOT_DELETE_PARTS);
	os_close(fd);
	return 0;

err_close_all:
	util_poolset_close(set, DO_NOT_DELETE_PARTS);

err_close_file:
	os_close(fd);

err:
	if (errno == 0)
		errno = EINVAL;

	return -1;
}
예제 #11
0
파일: set.c 프로젝트: bgbhpe/nvml
/*
 * util_poolset_open -- (internal) open memory pool set
 *
 * On success returns 0 and a pointer to a newly allocated structure
 * containing the info of all the parts of the pool set and replicas.
 */
static int
util_poolset_open(struct pool_set **setp, const char *path, size_t minsize)
{
	LOG(3, "setp %p path %s minsize %zu", setp, path, minsize);

	int oerrno;
	int ret = 0;
	int fd;
	size_t size = 0;

	/* do not check minsize */
	if ((fd = util_file_open(path, &size, 0, O_RDONLY)) == -1)
		return -1;

	char signature[POOLSET_HDR_SIG_LEN];
	/*
	 * read returns ssize_t, but we know it will return value between -1
	 * and POOLSET_HDR_SIG_LEN (11), so we can safely cast it to int
	 */
	ret = (int)read(fd, signature, POOLSET_HDR_SIG_LEN);
	if (ret < 0) {
		ERR("!read %d", fd);
		goto err;
	}

	if (ret < POOLSET_HDR_SIG_LEN ||
	    strncmp(signature, POOLSET_HDR_SIG, POOLSET_HDR_SIG_LEN)) {
		LOG(4, "not a pool set header");

		if (size < minsize) {
			ERR("size %zu smaller than %zu", size, minsize);
			errno = EINVAL;
			ret = -1;
			goto err;
		}

		/* close the file and open with O_RDWR */
		(void) close(fd);
		size = 0;
		if ((fd = util_file_open(path, &size, 0, O_RDWR)) == -1)
			return -1;

		*setp = util_poolset_single(path, size, fd, 0);
		if (*setp == NULL) {
			ret = -1;
			goto err;
		}

		/* do not close the file */
		return 0;
	}

	ret = util_poolset_parse(path, fd, setp);
	if (ret != 0)
		goto err;

	ret = util_poolset_files(*setp, minsize, 0);
	if (ret != 0)
		util_poolset_close(*setp, 0);

err:
	oerrno = errno;
	(void) close(fd);
	errno = oerrno;
	return ret;
}
예제 #12
0
파일: info.c 프로젝트: jebtang/nvml
/*
 * pmempool_setup_poolset -- parse poolset file and setup reading from it
 */
static int
pmempool_setup_poolset(struct pmem_info *pip)
{
	struct pool_set *set = NULL;
	int fd = -1;
	struct pool_hdr hdr;

	/* parse poolset file */
	if (util_poolset_parse(pip->file_name, pip->fd, &set)) {
		outv_err("parsing poolset file failed\n");
		return -1;
	}

	close(pip->fd);
	pip->fd = -1;

	/* open the first part set file to read the pool header values */
	int ret = 0;
	fd = util_file_open(set->replica[0]->part[0].path, NULL, 0, O_RDONLY);
	if (fd < 0) {
		outv_err("cannot open poolset part file\n");
		ret = -1;
		goto err_pool_set;
	}

	/* read the pool header from first pool set file */
	if (pread(fd, &hdr, sizeof (hdr), 0)
			!= sizeof (hdr)) {
		outv_err("cannot read pool header from poolset\n");
		ret = -1;
		goto err_close;
	}
	close(fd);
	fd = -1;

	util_convert2h_pool_hdr(&hdr);

	/* parse pool type from first pool set file */
	pmem_pool_type_t type = pmem_pool_type_parse_hdr(&hdr);
	if (type == PMEM_POOL_TYPE_UNKNOWN) {
		outv_err("cannot determine pool type from poolset\n");
		ret = -1;
		goto err_close;
	}

	/* get minimum size based on pool type for util_pool_open */
	size_t minsize = pmem_pool_get_min_size(type);

	/*
	 * Open the poolset, the values passed to util_pool_open are read
	 * from the first poolset file, these values are then compared with
	 * the values from all headers of poolset files.
	 */
	if (util_pool_open(&pip->poolset, pip->file_name, 1, minsize,
		sizeof (struct pool_hdr),
		hdr.signature, hdr.major,
		hdr.compat_features,
		hdr.incompat_features,
		hdr.ro_compat_features)) {
		outv_err("openning poolset failed\n");
		ret = -1;
	}

err_close:
	if (fd != -1)
		close(fd);
err_pool_set:
	util_poolset_free(set);

	return ret;

}
예제 #13
0
파일: rm.c 프로젝트: wojtuss/nvml
static inline
#endif
int
pmempool_rmU(const char *path, int flags)
{
	LOG(3, "path %s flags %x", path, flags);
	int ret;

	if (flags & ~PMEMPOOL_RM_ALL_FLAGS) {
		ERR("invalid flags specified");
		errno = EINVAL;
		return -1;
	}

	int is_poolset = util_is_poolset_file(path);
	if (is_poolset < 0) {
		os_stat_t buff;
		ret = os_stat(path, &buff);
		if (!ret) {
			if (S_ISDIR(buff.st_mode)) {
				errno = EISDIR;
				ERR("removing file failed");
				return -1;
			}
		}
		ERR_F(flags, "removing file failed");
		if (CHECK_FLAG(flags, FORCE))
			return 0;

		return -1;
	}

	if (!is_poolset) {
		LOG(2, "%s: not a poolset file", path);
		return rm_local(path, flags, 0);
	}

	LOG(2, "%s: poolset file", path);

	/* fill up pool_set structure */
	struct pool_set *set = NULL;
	int fd = os_open(path, O_RDONLY);
	if (fd == -1 || util_poolset_parse(&set, path, fd)) {
		ERR_F(flags, "parsing poolset file failed");
		if (fd != -1)
			os_close(fd);
		if (CHECK_FLAG(flags, FORCE))
			return 0;
		return -1;
	}
	os_close(fd);

	if (set->remote) {
		/* ignore error - it will be handled in rm_remote() */
		(void) util_remote_load();
	}

	util_poolset_free(set);

	struct cb_args args;
	args.flags = flags;
	args.error = 0;
	ret = util_poolset_foreach_part(path, rm_cb, &args);
	if (ret == -1) {
		ERR_F(flags, "parsing poolset file failed");
		if (CHECK_FLAG(flags, FORCE))
			return 0;

		return ret;
	}

	ASSERTeq(ret, 0);

	if (args.error)
		return args.error;

	if (CHECK_FLAG(flags, POOLSET_LOCAL)) {
		ret = rm_local(path, flags, 0);
		if (ret) {
			ERR_F(flags, "removing pool set file failed");
		} else {
			LOG(3, "%s: removed", path);
		}

		if (CHECK_FLAG(flags, FORCE))
			return 0;

		return ret;
	}

	return 0;
}