Beispiel #1
0
/*
 * remove_hdrs_replica -- (internal) remove headers from the replica
 */
static int
remove_hdrs_replica(struct pool_set *set_in, struct pool_set *set_out,
		unsigned repn)
{
	LOG(3, "set %p, repn %u", set_in, repn);
	int ret = 0;

	/* open all part files of the input replica */
	if (replica_open_replica_part_files(set_in, repn)) {
		LOG(1, "opening replica %u, part files failed", repn);
		ret = -1;
		goto out;
	}

	/* share part file descriptors between poolset structures */
	copy_part_fds(set_out, set_in);

	/* map the whole input replica */
	if (util_replica_open(set_in, repn, MAP_SHARED)) {
		LOG(1, "opening input replica failed: replica %u", repn);
		ret = -1;
		goto out_close;
	}

	/* map the whole output replica */
	if (util_replica_open(set_out, repn, MAP_SHARED)) {
		LOG(1, "opening output replica failed: replica %u", repn);
		ret = -1;
		goto out_unmap_in;
	}

	/* move data between the two mappings of the replica */
	if (REP(set_in, repn)->nparts > 1)
		copy_replica_data_fw(set_out, set_in, repn);

	/* make changes to the first part's header */
	update_replica_header(set_out, repn);

	util_replica_close(set_out, repn);
out_unmap_in:
	util_replica_close(set_in, repn);
out_close:
	util_replica_fdclose(REP(set_in, repn));
out:
	return ret;
}
Beispiel #2
0
/*
 * util_pool_open_nocheck -- open a memory pool (set or a single file)
 *
 * This function opens opens a pool set without checking the header values.
 */
int
util_pool_open_nocheck(struct pool_set **setp, const char *path, int rdonly,
		size_t hdrsize)
{
	LOG(3, "setp %p path %s", setp, path);

	int flags = rdonly ? MAP_PRIVATE|MAP_NORESERVE : MAP_SHARED;

	int ret = util_poolset_open(setp, path, 0);
	if (ret < 0) {
		LOG(2, "cannot open pool set");
		return -1;
	}

	struct pool_set *set = *setp;

	ASSERT(set->nreplicas > 0);

	set->rdonly = 0;
	set->poolsize = SIZE_MAX;

	for (unsigned r = 0; r < set->nreplicas; r++) {
		if (util_replica_open(set, r, flags, hdrsize) != 0) {
			LOG(2, "replica open failed");
			goto err;
		}
	}

	/* unmap all headers */
	for (unsigned r = 0; r < set->nreplicas; r++) {
		struct pool_replica *rep = set->replica[r];
		for (unsigned p = 0; p < rep->nparts; p++)
			util_unmap_hdr(&rep->part[p]);
	}

	return 0;

err:
	LOG(4, "error clean up");
	int oerrno = errno;
	for (unsigned r = 0; r < set->nreplicas; r++)
		util_replica_close(set, r);

	util_poolset_close(set, 0);
	errno = oerrno;
	return -1;
}
Beispiel #3
0
/*
 * util_pool_open -- open a memory pool (set or a single file)
 *
 * This routine does all the work, but takes a rdonly flag so internal
 * calls can map a read-only pool if required.
 */
int
util_pool_open(struct pool_set **setp, const char *path, int rdonly,
	size_t minsize, size_t hdrsize, const char *sig,
	uint32_t major, uint32_t compat, uint32_t incompat, uint32_t ro_compat)
{
	LOG(3, "setp %p path %s rdonly %d minsize %zu "
		"hdrsize %zu sig %s major %u "
		"compat %#x incompat %#x ro_comapt %#x",
		setp, path, rdonly, minsize, hdrsize,
		sig, major, compat, incompat, ro_compat);

	int flags = rdonly ? MAP_PRIVATE|MAP_NORESERVE : MAP_SHARED;

	int ret = util_poolset_open(setp, path, minsize);
	if (ret < 0) {
		LOG(2, "cannot open pool set");
		return -1;
	}

	struct pool_set *set = *setp;

	ASSERT(set->nreplicas > 0);

	set->rdonly = 0;
	set->poolsize = SIZE_MAX;

	for (unsigned r = 0; r < set->nreplicas; r++) {
		if (util_replica_open(set, r, flags, hdrsize) != 0) {
			LOG(2, "replica open failed");
			goto err;
		}
	}

	/* check headers, check UUID's, check replicas linkage */
	for (unsigned r = 0; r < set->nreplicas; r++) {
		struct pool_replica *rep = set->replica[r];
		for (unsigned p = 0; p < rep->nparts; p++) {
			if (util_header_check(set, r, p,  sig, major,
					compat, incompat, ro_compat) != 0) {
				LOG(2, "header check failed - part #%d", p);
				goto err;
			}

			set->rdonly |= rep->part[p].rdonly;
		}

		if (memcmp(HDR(REP(set, r - 1), 0)->uuid,
					HDR(REP(set, r), 0)->prev_repl_uuid,
					POOL_HDR_UUID_LEN) ||
		    memcmp(HDR(REP(set, r + 1), 0)->uuid,
					HDR(REP(set, r), 0)->next_repl_uuid,
					POOL_HDR_UUID_LEN)) {
			ERR("wrong replica UUID");
			errno = EINVAL;
			goto err;
		}
	}

	/* unmap all headers */
	for (unsigned r = 0; r < set->nreplicas; r++) {
		struct pool_replica *rep = set->replica[r];
		for (unsigned p = 0; p < rep->nparts; p++)
			util_unmap_hdr(&rep->part[p]);
	}

	return 0;

err:
	LOG(4, "error clean up");
	int oerrno = errno;
	for (unsigned r = 0; r < set->nreplicas; r++)
		util_replica_close(set, r);

	util_poolset_close(set, 0);
	errno = oerrno;
	return -1;
}
Beispiel #4
0
Datei: set.c Projekt: bgbhpe/nvml
/*
 * util_pool_open_remote -- open a remote pool set file
 *
 * This routine does all the work, but takes a rdonly flag so internal
 * calls can map a read-only pool if required.
 */
int
util_pool_open_remote(struct pool_set **setp, const char *path, int rdonly,
	size_t minsize, char *sig, uint32_t *major,
	uint32_t *compat, uint32_t *incompat, uint32_t *ro_compat,
	unsigned char *poolset_uuid, unsigned char *first_part_uuid,
	unsigned char *prev_repl_uuid, unsigned char *next_repl_uuid,
	unsigned char *arch_flags)
{
	LOG(3, "setp %p path %s rdonly %d minsize %zu "
		"sig %p major %p compat %p incompat %p ro_comapt %p"
		"poolset_uuid %p first_part_uuid %p"
		"prev_repl_uuid %p next_repl_uuid %p arch_flags %p",
		setp, path, rdonly, minsize,
		sig, major, compat, incompat, ro_compat,
		poolset_uuid, first_part_uuid, prev_repl_uuid, next_repl_uuid,
		arch_flags);

	int flags = rdonly ? MAP_PRIVATE|MAP_NORESERVE : MAP_SHARED;

	int ret = util_poolset_open(setp, path, minsize);
	if (ret < 0) {
		LOG(2, "cannot open pool set");
		return -1;
	}

	struct pool_set *set = *setp;

	if (set->nreplicas > 1) {
		LOG(2, "remote pool set cannot have replicas");
		goto err;
	}

	if (util_replica_open(set, 0, flags) != 0) {
		LOG(2, "replica open failed");
		goto err;
	}

	struct pool_replica *rep = set->replica[0];
	struct pool_hdr *hdr = rep->part[0].hdr;

	set->rdonly |= rep->part[0].rdonly;

	/* check headers, check UUID's, check replicas linkage */
	for (unsigned p = 0; p < rep->nparts; p++) {
		if (util_header_check_remote(rep, p) != 0) {
			LOG(2, "header check failed - part #%d", p);
			goto err;
		}
		set->rdonly |= rep->part[p].rdonly;
	}

	memcpy(sig, hdr->signature, POOL_HDR_SIG_LEN);
	*major = hdr->major;
	*compat = hdr->compat_features;
	*incompat = hdr->incompat_features;
	*ro_compat = hdr->ro_compat_features;
	memcpy(poolset_uuid, hdr->poolset_uuid, POOL_HDR_UUID_LEN);
	memcpy(first_part_uuid, hdr->uuid, POOL_HDR_UUID_LEN);
	memcpy(prev_repl_uuid, hdr->prev_repl_uuid, POOL_HDR_UUID_LEN);
	memcpy(next_repl_uuid, hdr->next_repl_uuid, POOL_HDR_UUID_LEN);
	memcpy(arch_flags, &hdr->arch_flags, sizeof(struct arch_flags));

	/* unmap all headers */
	for (unsigned p = 0; p < rep->nparts; p++)
		util_unmap_hdr(&rep->part[p]);

	return 0;

err:
	LOG(4, "error clean up");
	int oerrno = errno;
	util_replica_close(set, 0);
	util_poolset_close(set, 0);
	errno = oerrno;
	return -1;
}
Beispiel #5
0
/*
 * add_hdrs_replica -- (internal) add lacking headers to the replica
 *
 * when the operation fails and returns -1, the replica remains untouched
 */
static int
add_hdrs_replica(struct pool_set *set_in, struct pool_set *set_out,
		unsigned repn)
{
	LOG(3, "set %p, repn %u", set_in, repn);
	int ret = 0;

	/* open all part files of the input replica */
	if (replica_open_replica_part_files(set_in, repn)) {
		LOG(1, "opening replica %u, part files failed", repn);
		ret = -1;
		goto out;
	}

	/* share part file descriptors between poolset structures */
	copy_part_fds(set_out, set_in);

	/* map the whole input replica */
	if (util_replica_open(set_in, repn, MAP_SHARED)) {
		LOG(1, "opening input replica failed: replica %u", repn);
		ret = -1;
		goto out_close;
	}

	/* map the whole output replica */
	if (util_replica_open(set_out, repn, MAP_SHARED)) {
		LOG(1, "opening output replica failed: replica %u", repn);
		ret = -1;
		goto out_unmap_in;
	}

	/* generate new uuids for lacking headers */
	if (fill_replica_struct_uuids(set_out, repn)) {
		LOG(1, "generating lacking uuids for parts failed: replica %u",
				repn);
		ret = -1;
		goto out_unmap_out;
	}

	/* copy data between the two mappings of the replica */
	if (REP(set_in, repn)->nparts > 1)
		copy_replica_data_bw(set_out, set_in, repn);

	/* create the missing headers */
	if (create_missing_headers(set_out, repn)) {
		LOG(1, "creating lacking headers failed: replica %u", repn);
		/*
		 * copy the data back, so we could fall back to the original
		 * state
		 */
		if (REP(set_in, repn)->nparts > 1)
			copy_replica_data_fw(set_in, set_out, repn);
		ret = -1;
		goto out_unmap_out;
	}

	/* make changes to the first part's header */
	update_replica_header(set_out, repn);

	/* store new uuids in all headers and update linkage in the replica */
	update_uuids(set_out, repn);

out_unmap_out:
	util_replica_close(set_out, repn);
out_unmap_in:
	util_replica_close(set_in, repn);
out_close:
	util_replica_fdclose(REP(set_in, repn));
out:
	return ret;
}