Ejemplo n.º 1
0
int
main(int argc, char *argv[])
{
	START(argc, argv, "util_poolset");

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

	if (argc < 3)
		UT_FATAL("usage: %s cmd minsize [mockopts] "
			"setfile ...", argv[0]);

	char *fname;
	struct pool_set *set;
	int ret;

	size_t minsize = strtoul(argv[2], &fname, 0);

	for (int arg = 3; arg < argc; arg++) {
		arg += mock_options(argv[arg]);
		fname = argv[arg];
		struct pool_attr attr;
		memset(&attr, 0, sizeof(attr));
		memcpy(attr.signature, SIG, sizeof(SIG));
		attr.major = 1;

		switch (argv[1][0]) {
		case 'c':
			ret = util_pool_create(&set, fname, 0, minsize,
				MIN_PART, &attr, NULL, REPLICAS_ENABLED);
			if (ret == -1)
				UT_OUT("!%s: util_pool_create", fname);
			else {
				/*
				 * XXX: On Windows pool files are created with
				 * R/W permissions, so no need for chmod().
				 */
#ifndef _WIN32
				util_poolset_chmod(set, S_IWUSR | S_IRUSR);
#endif
				poolset_info(fname, set, 0);
				util_poolset_close(set, DO_NOT_DELETE_PARTS);
			}
			break;
		case 'o':
			attr.incompat_features = TEST_FORMAT_INCOMPAT_CHECK;
			ret = util_pool_open(&set, fname, 0 /* rdonly */,
				MIN_PART, &attr, NULL, false, NULL);
			if (ret == -1)
				UT_OUT("!%s: util_pool_open", fname);
			else {
				poolset_info(fname, set, 1);
				util_poolset_close(set, DO_NOT_DELETE_PARTS);
			}
			break;
		case 'e':
			attr.incompat_features = TEST_FORMAT_INCOMPAT_CHECK;
			ret = util_pool_open(&set, fname, 0 /* rdonly */,
				MIN_PART, &attr, NULL, false, NULL);
			UT_ASSERTeq(ret, 0);
			void *nptr = util_pool_extend(set, Extend_size);
			if (nptr == NULL)
				UT_OUT("!%s: util_pool_extend", fname);
			else {
				poolset_info(fname, set, 1);
			}
			util_poolset_close(set, DO_NOT_DELETE_PARTS);
			break;
		}
	}

	common_fini();

	DONE(NULL);
}
Ejemplo n.º 2
0
/*
 * pmemobj_open_common -- open a transactional memory pool (set)
 *
 * This routine does all the work, but takes a cow flag so internal
 * calls can map a read-only pool if required.
 */
static PMEMobjpool *
pmemobj_open_common(const char *path, const char *layout, int cow, int boot)
{
	LOG(3, "path %s layout %s cow %d", path, layout, cow);

	struct pool_set *set;

	if (util_pool_open(&set, path, cow, PMEMOBJ_MIN_POOL,
			roundup(sizeof (struct pmemobjpool), Pagesize),
			OBJ_HDR_SIG, OBJ_FORMAT_MAJOR,
			OBJ_FORMAT_COMPAT, OBJ_FORMAT_INCOMPAT,
			OBJ_FORMAT_RO_COMPAT) != 0) {
		LOG(2, "cannot open pool or pool set");
		return NULL;
	}

	ASSERT(set->nreplicas > 0);

	/* read-only mode is not supported in libpmemobj */
	if (set->rdonly) {
		ERR("read-only mode is not supported");
		errno = EINVAL;
		goto err;
	}

	PMEMobjpool *pop;
	for (unsigned r = 0; r < set->nreplicas; r++) {
		struct pool_replica *rep = set->replica[r];
		pop = rep->part[0].addr;

		VALGRIND_REMOVE_PMEM_MAPPING(&pop->addr,
			sizeof (struct pmemobjpool) -
			((uintptr_t)&pop->addr - (uintptr_t)&pop->hdr));

		pop->addr = pop;
		pop->size = rep->repsize;

		if (pmemobj_descr_check(pop, layout, set->poolsize) != 0) {
			LOG(2, "descriptor check failed");
			goto err;
		}

		/* initialize replica runtime - is_pmem, funcs, ... */
		if (pmemobj_replica_init(pop, rep->is_pmem) != 0) {
			ERR("pool initialization failed");
			goto err;
		}

		/* link replicas */
		if (r < set->nreplicas - 1)
			pop->replica = set->replica[r + 1]->part[0].addr;
	}

	/*
	 * If there is more than one replica, check if all of them are
	 * consistent (recoverable).
	 * On success, choose any replica and copy entire lanes (redo logs)
	 * to all the other replicas to synchronize them.
	 */
	if (set->nreplicas > 1) {
		for (unsigned r = 0; r < set->nreplicas; r++) {
			pop = set->replica[r]->part[0].addr;
			if (pmemobj_check_basic(pop) == 0) {
				ERR("inconsistent replica #%u", r);
				goto err;
			}
		}

		/* copy lanes */
		pop = set->replica[0]->part[0].addr;
		void *src = (void *)((uintptr_t)pop + pop->lanes_offset);
		size_t len = pop->nlanes * sizeof (struct lane_layout);

		for (unsigned r = 1; r < set->nreplicas; r++) {
			pop = set->replica[r]->part[0].addr;
			void *dst = (void *)((uintptr_t)pop +
						pop->lanes_offset);
			pop->memcpy_persist_local(dst, src, len);
		}
	}

	pop = set->replica[0]->part[0].addr;
	pop->is_master_replica = 1;

	for (unsigned r = 1; r < set->nreplicas; r++) {
		PMEMobjpool *rep = set->replica[r]->part[0].addr;
		rep->is_master_replica = 0;
	}

#ifdef USE_VG_MEMCHECK
	heap_vg_open(pop);
#endif

	VALGRIND_DO_CREATE_MEMPOOL(pop, 0, 0);

	/* initialize runtime parts - lanes, obj stores, ... */
	if (pmemobj_runtime_init(pop, 0, boot) != 0) {
		ERR("pool initialization failed");
		goto err;
	}

	util_poolset_fdclose(set);
	util_poolset_free(set);

#ifdef USE_VG_MEMCHECK
	if (boot)
		pmemobj_vg_boot(pop);
#endif

	LOG(3, "pop %p", pop);

	return pop;

err:
	LOG(4, "error clean up");
	int oerrno = errno;
	util_poolset_close(set, 0);
	errno = oerrno;
	return NULL;
}
Ejemplo n.º 3
0
Archivo: info.c Proyecto: 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;

}
Ejemplo n.º 4
0
/*
 * blk_open_common -- (internal) open a block memory pool
 *
 * This routine does all the work, but takes a cow flag so internal
 * calls can map a read-only pool if required.
 *
 * Passing in bsize == 0 means a valid pool header must exist (which
 * will supply the block size).
 */
static PMEMblkpool *
blk_open_common(const char *path, size_t bsize, int cow)
{
	LOG(3, "path %s bsize %zu cow %d", path, bsize, cow);

	struct pool_set *set;

	if (util_pool_open(&set, path, cow, PMEMBLK_MIN_POOL,
			BLK_HDR_SIG, BLK_FORMAT_MAJOR,
			BLK_FORMAT_COMPAT, BLK_FORMAT_INCOMPAT,
			BLK_FORMAT_RO_COMPAT, NULL) != 0) {
		LOG(2, "cannot open pool or pool set");
		return NULL;
	}

	ASSERT(set->nreplicas > 0);

	struct pool_replica *rep = set->replica[0];
	PMEMblkpool *pbp = rep->part[0].addr;

	VALGRIND_REMOVE_PMEM_MAPPING(&pbp->addr,
			sizeof(struct pmemblk) -
			((uintptr_t)&pbp->addr - (uintptr_t)&pbp->hdr));

	pbp->addr = pbp;
	pbp->size = rep->repsize;
	pbp->set = set;
	pbp->is_pmem = rep->is_pmem;
	pbp->is_dev_dax = rep->part[0].is_dev_dax;

	/* is_dev_dax implies is_pmem */
	ASSERT(!pbp->is_dev_dax || pbp->is_pmem);

	if (set->nreplicas > 1) {
		errno = ENOTSUP;
		ERR("!replicas not supported");
		goto err;
	}

	/* validate pool descriptor */
	if (blk_descr_check(pbp, &bsize) != 0) {
		LOG(2, "descriptor check failed");
		goto err;
	}

	/* initialize runtime parts */
	if (blk_runtime_init(pbp, bsize, set->rdonly) != 0) {
		ERR("pool initialization failed");
		goto err;
	}

	util_poolset_fdclose(set);

	LOG(3, "pbp %p", pbp);
	return pbp;

err:
	LOG(4, "error clean up");
	int oerrno = errno;
	util_poolset_close(set, DO_NOT_DELETE_PARTS);
	errno = oerrno;
	return NULL;
}