Beispiel #1
0
/*
 * pmempool_sync -- synchronize replicas within a poolset
 */
int
pmempool_sync(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) {
		if (util_remote_load()) {
			ERR("remote replication not available");
			goto err_close_file;
		}
	}

	/* sync all replicas */
	if (replica_sync(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;
}
Beispiel #2
0
/*
 * transform_replica -- transforming one poolset into another
 */
int
replica_transform(struct pool_set *set_in, struct pool_set *set_out,
		unsigned flags)
{
	LOG(3, "set_in %p, set_out %p", set_in, set_out);

	int ret = 0;
	/* validate user arguments */
	if (validate_args(set_in, set_out))
		return -1;

	/* 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");
		return -1;
	}

	if (!replica_is_poolset_healthy(set_in_hs)) {
		ERR("source poolset is broken");
		ret = -1;
		errno = EINVAL;
		goto free_hs_in;
	}

	struct poolset_health_status *set_out_hs = NULL;
	if (replica_create_poolset_health_status(set_out, &set_out_hs)) {
		ERR("creating poolset health status failed");
		ret = -1;
		goto free_hs_in;
	}

	/* check if the poolsets are transformable */
	struct poolset_compare_status *set_in_cs = NULL;
	struct poolset_compare_status *set_out_cs = NULL;
	if (compare_poolsets(set_in, set_out, &set_in_cs, &set_out_cs)) {
		ERR("comparing poolsets failed");
		ret = -1;
		goto free_hs_out;
	}

	enum transform_op operation = identify_transform_operation(set_in_cs,
			set_out_cs, set_in_hs, set_out_hs);

	if (operation == NOT_TRANSFORMABLE) {
		LOG(1, "poolsets are not transformable");
		ret = -1;
		errno = EINVAL;
		goto free_cs;
	}

	if (operation == RM_HDRS) {
		if (!is_dry_run(flags) &&
				remove_hdrs(set_in, set_out, set_in_hs,
						flags)) {
			ERR("removing headers failed; falling back to the "
					"input poolset");
			if (replica_sync(set_in, set_in_hs,
					flags | IS_TRANSFORMED)) {
				LOG(1, "falling back to the input poolset "
						"failed");
			} else {
				LOG(1, "falling back to the input poolset "
						"succeeded");
			}
			ret = -1;
		}
		goto free_cs;
	}

	if (operation == ADD_HDRS) {
		if (!is_dry_run(flags) &&
				add_hdrs(set_in, set_out, set_in_hs, flags)) {
			ERR("adding headers failed; falling back to the "
					"input poolset");
			if (replica_sync(set_in, set_in_hs,
					flags | IS_TRANSFORMED)) {
				LOG(1, "falling back to the input poolset "
						"failed");
			} else {
				LOG(1, "falling back to the input poolset "
						"succeeded");
			}
			ret = -1;
		}
		goto free_cs;
	}

	if (operation == ADD_REPLICAS) {
		/*
		 * check if any of the parts that are to be added already exists
		 */
		if (do_added_parts_exist(set_out, set_out_hs)) {
			ERR("some parts being added already exist");
			ret = -1;
			errno = EINVAL;
			goto free_cs;
		}
	}

	/* signal that sync is called by transform */
	if (replica_sync(set_out, set_out_hs, flags | IS_TRANSFORMED)) {
		ret = -1;
		goto free_cs;
	}

	if (operation == RM_REPLICAS) {
		if (!is_dry_run(flags) && delete_replicas(set_in, set_in_cs))
			ret = -1;
	}

free_cs:
	Free(set_in_cs);
	Free(set_out_cs);
free_hs_out:
	replica_free_poolset_health_status(set_out_hs);
free_hs_in:
	replica_free_poolset_health_status(set_in_hs);
	return ret;
}