示例#1
0
文件: farm.c 项目: Vinchal/sheepdog
static int farm_snapshot(const struct siocb *iocb)
{
	unsigned char snap_sha1[SHA1_LEN];
	unsigned char trunk_sha1[SHA1_LEN];
	struct sd_node nodes[SD_MAX_NODES];
	int nr_nodes;
	void *buffer;
	int log_nr, ret = SD_RES_EIO, epoch;

	buffer = snap_log_read(&log_nr);
	if (!buffer)
		goto out;

	epoch = log_nr + 1;
	sd_dprintf("user epoch %d", epoch);

	nr_nodes = epoch_log_read(sys->epoch, nodes, sizeof(nodes));
	if (nr_nodes < 0)
		goto out;

	if (trunk_file_write(trunk_sha1) < 0)
		goto out;

	if (snap_file_write(sys->epoch, nodes, nr_nodes,
			    trunk_sha1, snap_sha1) < 0)
		goto out;

	if (snap_log_write(epoch, snap_sha1) < 0)
		goto out;

	ret = SD_RES_SUCCESS;
out:
	free(buffer);
	return ret;
}
示例#2
0
文件: snap.c 项目: douardda/sheepdog
int snap_file_write(uint32_t epoch, unsigned char *trunksha1, unsigned char *outsha1, int user)
{
	int ret = 0;
	struct strbuf buf = STRBUF_INIT;
	struct sd_node nodes[SD_MAX_NODES];
	int tgt_epoch = user ? sys_epoch() : epoch;
	uint64_t epoch_size;
	struct sha1_file_hdr hdr;

	epoch_size = epoch_log_read(tgt_epoch, (char *)nodes, sizeof(nodes));
	if (epoch_size == -1)
		return -1;

	memcpy(hdr.tag, TAG_SNAP, TAG_LEN);
	hdr.size = epoch_size + SHA1_LEN;
	hdr.priv = tgt_epoch;
	hdr.reserved = 0;

	strbuf_add(&buf, &hdr, sizeof(hdr));
	strbuf_add(&buf, trunksha1, SHA1_LEN);
	strbuf_add(&buf, (char *)nodes, epoch_size);
	if (sha1_file_write((void *)buf.buf, buf.len, outsha1) < 0) {
		ret = -1;
		goto err;
	}

	dprintf("epoch %u, sha1: %s\n", epoch, sha1_to_hex(outsha1));
err:
	strbuf_release(&buf);
	return ret;
}
示例#3
0
文件: group.c 项目: wiedi/sheepdog
static int get_nodes_nr_epoch(uint32_t epoch)
{
	struct sd_node nodes[SD_MAX_NODES];
	int nr;

	nr = epoch_log_read(epoch, (char *)nodes, sizeof(nodes));
	nr /= sizeof(nodes[0]);
	return nr;
}
示例#4
0
文件: group.c 项目: drscream/sheepdog
struct vnode_info *get_vnode_info_epoch(uint32_t epoch)
{
	struct sd_node nodes[SD_MAX_NODES];
	int nr_nodes;

	nr_nodes = epoch_log_read(epoch, nodes, sizeof(nodes));
	if (nr_nodes < 0) {
		nr_nodes = epoch_log_read_remote(epoch, nodes, sizeof(nodes));
		if (nr_nodes == 0)
			return NULL;
	}

	return alloc_vnode_info(nodes, nr_nodes);
}
示例#5
0
文件: group.c 项目: drscream/sheepdog
static struct sd_node *find_entry_epoch(struct sd_node *entry,
					uint32_t epoch)
{
	struct sd_node nodes[SD_MAX_NODES];
	int nr, i;

	if (!epoch)
		return NULL;

	nr = epoch_log_read(epoch, nodes, sizeof(nodes));

	for (i = 0; i < nr; i++)
		if (node_eq(&nodes[i], entry))
			return entry;

	return NULL;
}
示例#6
0
文件: group.c 项目: drscream/sheepdog
static int cluster_wait_for_join_check(struct sd_node *joined,
		struct join_message *jm)
{
	struct sd_node local_entries[SD_MAX_NODES];
	int nr, nr_local_entries, nr_failed_entries, nr_delayed_nodes;
	uint32_t local_epoch = get_latest_epoch();
	int ret;

	if (jm->nr_nodes == 0)
		return CJ_RES_JOIN_LATER;

	ret = cluster_sanity_check(jm);
	if (ret != CJ_RES_SUCCESS)  {
		if (jm->epoch > sys->epoch) {
			eprintf("transfer mastership (%d, %d)\n",
				jm->epoch, sys->epoch);
			return CJ_RES_MASTER_TRANSFER;
		}
		return ret;
	}

	nr_local_entries = epoch_log_read(jm->epoch, local_entries,
					  sizeof(local_entries));
	if (nr_local_entries == -1)
		return CJ_RES_FAIL;

	if (jm->epoch < local_epoch) {
		eprintf("joining node epoch too small: %"
			PRIu32 " vs %" PRIu32 "\n",
			jm->epoch, local_epoch);
		return CJ_RES_JOIN_LATER;
	}

	if (jm->nr_nodes != nr_local_entries) {
		eprintf("epoch log entries do not match: %d vs %d\n",
			jm->nr_nodes, nr_local_entries);
		return CJ_RES_FAIL;
	}


	if (memcmp(jm->nodes, local_entries,
		   sizeof(jm->nodes[0]) * jm->nr_nodes) != 0) {
		eprintf("epoch log entries does not match\n");
		return CJ_RES_FAIL;
	}

	if (!current_vnode_info)
		nr = 1;
	else
		nr = current_vnode_info->nr_nodes + 1;

	nr_delayed_nodes = get_nodes_nr_from(&sys->delayed_nodes);

	/*
	 * If we have all members from the last epoch log in the in-memory
	 * node list, and no new nodes joining we can set the cluster live
	 * now without incrementing the epoch.
	 */
	if (nr == nr_local_entries && !nr_delayed_nodes) {
		jm->cluster_status = SD_STATUS_OK;
		return CJ_RES_SUCCESS;
	}

	/*
	 * If we reach the old node count, but some node failed we have to
	 * update the epoch before setting the cluster live.
	 */
	nr_failed_entries = get_nodes_nr_from(&sys->failed_nodes);
	if (nr_local_entries == nr + nr_failed_entries - nr_delayed_nodes) {
		jm->inc_epoch = 1;
		jm->cluster_status = SD_STATUS_OK;
		return CJ_RES_SUCCESS;
	}

	/*
	 * The join was successful, but we don't have enough nodes yet to set
	 * the cluster live.
	 */
	return CJ_RES_SUCCESS;
}
示例#7
0
文件: group.c 项目: drscream/sheepdog
static int get_nodes_nr_epoch(uint32_t epoch)
{
	struct sd_node nodes[SD_MAX_NODES];

	return epoch_log_read(epoch, nodes, sizeof(nodes));
}