예제 #1
0
/*
 * replica_check_poolset_health -- check if a given poolset can be considered as
 *                         healthy, and store the status in a helping structure
 */
int
replica_check_poolset_health(struct pool_set *set,
		struct poolset_health_status **set_hsp, unsigned flags)
{
	if (replica_create_poolset_health_status(set, set_hsp)) {
		LOG(1, "Creating poolset health status failed");
		return -1;
	}

	struct poolset_health_status *set_hs = *set_hsp;

	/* check if part files exist, and if not - create them, and open them */
	check_and_open_poolset_part_files(set, set_hs, flags);

	/* map all headers */
	map_all_unbroken_headers(set, set_hs);

	/* check if checksums are correct for parts in all replicas */
	check_checksums(set, set_hs);

	/* check if uuids in parts across each replica are consistent */
	if (check_replicas_consistency(set, set_hs)) {
		LOG(1, "Replica consistency check failed");
		goto err;
	}

	/* check poolset_uuid values between replicas */
	if (check_poolset_uuids(set, set_hs)) {
		LOG(1, "Poolset uuids check failed");
		goto err;
	}

	/* check if uuids for adjacent replicas are consistent */
	if (check_uuids_between_replicas(set, set_hs)) {
		LOG(1, "Replica uuids check failed");
		goto err;
	}

	if (check_store_all_sizes(set, set_hs)) {
		LOG(1, "Reading pool sizes failed");
		goto err;
	}

	unmap_all_headers(set);
	util_poolset_fdclose(set);
	return 0;

err:
	unmap_all_headers(set);
	util_poolset_fdclose(set);
	replica_free_poolset_health_status(set_hs);
	return -1;
}
예제 #2
0
파일: replica.c 프로젝트: wojtuss/nvml
/*
 * replica_check_poolset_health -- check if a given poolset can be considered as
 *                         healthy, and store the status in a helping structure
 */
int
replica_check_poolset_health(struct pool_set *set,
		struct poolset_health_status **set_hsp, unsigned flags)
{
	LOG(3, "set %p, set_hsp %p, flags %u", set, set_hsp, flags);
	if (replica_create_poolset_health_status(set, set_hsp)) {
		LOG(1, "creating poolset health status failed");
		return -1;
	}

	struct poolset_health_status *set_hs = *set_hsp;

	/* check if part files exist, and if not - create them, and open them */
	check_and_open_poolset_part_files(set, set_hs, flags);

	/* map all headers */
	map_all_unbroken_headers(set, set_hs);

	/* check if checksums are correct for parts in all replicas */
	check_checksums(set, set_hs);

	/* check if option flags are consistent */
	if (check_options(set, set_hs)) {
		LOG(1, "flags check failed");
		goto err;
	}

	if (check_shutdown_state(set, set_hs)) {
		LOG(1, "replica shutdown_state check failed");
		goto err;
	}

	/* check if uuids in parts across each replica are consistent */
	if (check_replicas_consistency(set, set_hs)) {
		LOG(1, "replica consistency check failed");
		goto err;
	}

	/* check poolset_uuid values between replicas */
	if (check_poolset_uuids(set, set_hs)) {
		LOG(1, "poolset uuids check failed");
		goto err;
	}

	/* check if uuids for adjacent replicas are consistent */
	if (check_uuids_between_replicas(set, set_hs)) {
		LOG(1, "replica uuids check failed");
		goto err;
	}

	/* check if healthy replicas make up another poolset */
	if (check_replica_cycles(set, set_hs)) {
		LOG(1, "replica cycles check failed");
		goto err;
	}

	/* check if replicas are large enough */
	if (check_replica_sizes(set, set_hs)) {
		LOG(1, "replica sizes check failed");
		goto err;
	}

	if (check_store_all_sizes(set, set_hs)) {
		LOG(1, "reading pool sizes failed");
		goto err;
	}

	unmap_all_headers(set);
	util_poolset_fdclose_always(set);
	return 0;

err:
	errno = EINVAL;
	unmap_all_headers(set);
	util_poolset_fdclose_always(set);
	replica_free_poolset_health_status(set_hs);
	return -1;
}
예제 #3
0
파일: transform.c 프로젝트: GBuella/nvml
/*
 * 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;
}