Esempio n. 1
0
/*
 * check_replica_sizes -- (internal) check if all replicas are large
 *	enough to hold data from a healthy replica
 */
static int
check_replica_sizes(struct pool_set *set, struct poolset_health_status *set_hs)
{
	LOG(3, "set %p, set_hs %p", set, set_hs);
	ssize_t pool_size = -1;
	for (unsigned r = 0; r < set->nreplicas; ++r) {
		/* skip broken replicas */
		if (!replica_is_replica_healthy(r, set_hs))
			continue;

		/* get the size of a pool in the replica */
		ssize_t replica_pool_size;
		if (REP(set, r)->remote)
			/* XXX: no way to get the size of a remote pool yet */
			replica_pool_size = (ssize_t)set->poolsize;
		else
			replica_pool_size = replica_get_pool_size(set, r);

		if (replica_pool_size < 0) {
			LOG(1, "getting pool size from replica %u failed", r);
			set_hs->replica[r]->flags |= IS_BROKEN;
			continue;
		}

		/* check if the pool is bigger than minimum size */
		enum pool_type type = pool_hdr_get_type(HDR(REP(set, r), 0));
		if ((size_t)replica_pool_size < pool_get_min_size(type)) {
			LOG(1,
			"pool size from replica %u is smaller than the minimum size allowed for the pool",
			r);
			set_hs->replica[r]->flags |= IS_BROKEN;
			continue;
		}

		/* check if each replica is big enough to hold the pool data */
		if (set->poolsize < (size_t)replica_pool_size) {
			ERR(
			"some replicas are too small to hold synchronized data");
			return -1;
		}

		if (pool_size < 0) {
			pool_size = replica_pool_size;
			continue;
		}

		/* check if pools in all healthy replicas are of equal size */
		if (pool_size != replica_pool_size) {
			ERR("pool sizes from different replicas differ");
			return -1;
		}
	}
	return 0;
}
Esempio n. 2
0
/*
 * check_replica_sizes -- (internal) check if all replicas are large
 *	enough to hold data from a healthy replica
 */
static int
check_replica_sizes(struct pool_set *set, struct poolset_health_status *set_hs)
{
	LOG(3, "set %p, set_hs %p", set, set_hs);
	unsigned healthy_replica = replica_find_healthy_replica(set_hs);
	if (set->poolsize < replica_get_pool_size(set, healthy_replica)) {
		ERR("some replicas are too small to hold synchronized data");
		return -1;
	}

	return 0;
}
Esempio n. 3
0
/*
 * validate_args -- (internal) check whether passed arguments are valid
 */
static int
validate_args(struct pool_set *set_in, struct pool_set *set_out)
{
	LOG(3, "set_in %p, set_out %p", set_in, set_out);

	if (set_in->directory_based) {
		ERR("transform of directory poolsets is not supported");
		errno = EINVAL;
		return -1;
	}

	/*
	 * check if all parts in the target poolset are large enough
	 * (now replication works only for pmemobj pools)
	 */
	if (replica_check_part_sizes(set_out, PMEMOBJ_MIN_POOL)) {
		ERR("part sizes check failed");
		return -1;
	}

	/*
	 * check if all directories for part files exist and if part files
	 * do not reoccur in the poolset
	 */
	if (check_paths(set_out))
		return -1;

	/*
	 * check if set_out has enough size, i.e. if the target poolset
	 * structure has enough capacity to accommodate the effective size of
	 * the source poolset
	 */
	ssize_t master_pool_size = replica_get_pool_size(set_in, 0);
	if (master_pool_size < 0) {
		ERR("getting pool size from master replica failed");
		return -1;
	}

	if (set_out->poolsize < (size_t)master_pool_size) {
		ERR("target poolset is too small");
		errno = EINVAL;
		return -1;
	}

	return 0;
}
Esempio n. 4
0
File: sync.c Progetto: janekmi/nvml
/*
 * copy_data_to_broken_parts -- (internal) copy data to all parts created
 *                              in place of the broken ones
 */
static int
copy_data_to_broken_parts(struct pool_set *set, unsigned healthy_replica,
		unsigned flags, struct poolset_health_status *set_hs)
{
	size_t poolsize = replica_get_pool_size(set, healthy_replica);
	for (unsigned r = 0; r < set_hs->nreplicas; ++r) {
		/* skip unbroken and consistent replicas */
		if (replica_is_replica_healthy(r, set_hs))
			continue;

		struct pool_replica *rep = REP(set, r);
		struct pool_replica *rep_h = REP(set, healthy_replica);

		for (unsigned p = 0; p < rep->nparts; ++p) {
			/* skip unbroken parts from consistent replicas */
			if (!replica_is_part_broken(r, p, set_hs) &&
				replica_is_replica_consistent(r, set_hs))
				continue;

			const struct pool_set_part *part = &rep->part[p];

			size_t off = replica_get_part_data_offset(set, r, p);
			size_t len = replica_get_part_data_len(set, r, p);

			/* do not allow copying too much data */
			if (off >= poolsize)
				continue;

			if (off + len > poolsize)
				len = poolsize - off;

			void *src_addr = ADDR_SUM(rep_h->part[0].addr, off);

			/* First part of replica is mapped with header */
			size_t fpoff = (p == 0) ? POOL_HDR_SIZE : 0;

			/* copy all data */
			if (!is_dry_run(flags)) {
				memcpy(ADDR_SUM(part->addr, fpoff),
						src_addr, len);
				pmem_msync(ADDR_SUM(part->addr, fpoff), len);
			}
		}
	}
	return 0;
}
Esempio n. 5
0
/*
 * copy_replica_data_bw -- (internal) copy data between replicas of two
 *                         poolsets, starting from the end of the pool
 */
static void
copy_replica_data_bw(struct pool_set *set_dst, struct pool_set *set_src,
		unsigned repn)
{
	LOG(3, "set_in %p, set_out %p, repn %u", set_src, set_dst, repn);
	ssize_t pool_size = replica_get_pool_size(set_src, repn);
	if (pool_size < 0) {
		LOG(1, "getting pool size from replica %u failed", repn);
		pool_size = (ssize_t)set_src->poolsize;
	}

	size_t len = (size_t)pool_size - POOL_HDR_SIZE -
			replica_get_part_data_len(set_src, repn, 0);
	size_t count = len / POOL_HDR_SIZE;
	void *src = ADDR_SUM(PART(REP(set_src, repn), 1)->addr, len);
	void *dst = ADDR_SUM(PART(REP(set_dst, repn), 1)->addr, len);
	while (count-- > 0) {
		src = ADDR_SUM(src, -(ssize_t)POOL_HDR_SIZE);
		dst = ADDR_SUM(dst, -(ssize_t)POOL_HDR_SIZE);
		pmem_memcpy_persist(dst, src, POOL_HDR_SIZE);
	}
}