コード例 #1
0
ファイル: local.c プロジェクト: Nexenta/sheepdog
/*
 * Returns true if an event is processed
 */
static bool local_process_event(void)
{
	struct local_event *ev;
	enum cluster_join_result res;

	ev = shm_queue_peek();
	if (!ev)
		return false;

	switch (ev->type) {
	case EVENT_JOIN_REQUEST:
		if (!node_eq(&ev->nodes[0], &this_node))
			return false;

		res = sd_check_join_cb(&ev->sender, ev->buf);
		ev->join_result = res;
		ev->type = EVENT_JOIN_RESPONSE;
		msync(ev, sizeof(*ev), MS_SYNC);

		shm_queue_notify();

		if (res == CJ_RES_MASTER_TRANSFER) {
			eprintf("failed to join sheepdog cluster: "
				"please retry when master is up\n");
			shm_queue_unlock();
			exit(1);
		}
		return false;
	case EVENT_JOIN_RESPONSE:
		if (ev->join_result == CJ_RES_MASTER_TRANSFER) {
			/* FIXME: This code is tricky, but Sheepdog assumes that */
			/* nr_nodes = 1 when join_result = MASTER_TRANSFER... */
			ev->nr_nodes = 1;
			ev->nodes[0] = this_node;
			ev->pids[0] = getpid();

			shm_queue_set_chksum();
		}

		sd_join_handler(&ev->sender, ev->nodes, ev->nr_nodes,
				    ev->join_result, ev->buf);
		shm_queue_pop();
		break;
	case EVENT_LEAVE:
		sd_leave_handler(&ev->sender, ev->nodes, ev->nr_nodes);
		shm_queue_pop();
		break;
	case EVENT_BLOCK:
		sd_block_handler(&ev->sender);
		return false;
	case EVENT_NOTIFY:
		sd_notify_handler(&ev->sender, ev->buf, ev->buf_len);
		shm_queue_pop();
		break;
	}

	return true;
}
コード例 #2
0
ファイル: local.c プロジェクト: ke4qqq/sheepdog
static int local_dispatch(void)
{
	int ret;
	struct signalfd_siginfo siginfo;
	struct local_event *ev;
	enum cluster_join_result res;
	static struct work work = {
		.fn = local_block,
		.done = local_block_done,
	};

	dprintf("read siginfo\n");
	ret = read(sigfd, &siginfo, sizeof(siginfo));
	assert(ret == sizeof(siginfo));

	shm_queue_lock();

	ev = shm_queue_peek();
	if (!ev)
		goto out;

	switch (ev->type) {
	case EVENT_JOIN:
		if (ev->blocked) {
			if (node_cmp(&ev->nodes[0], &this_node) == 0) {
				res = local_check_join_cb(&ev->sender, ev->buf);
				ev->join_result = res;
				ev->blocked = 0;
				msync(ev, sizeof(*ev), MS_SYNC);

				shm_queue_notify();

				if (res == CJ_RES_MASTER_TRANSFER) {
					eprintf("failed to join sheepdog cluster: please retry when master is up\n");
					shm_queue_unlock();
					exit(1);
				}
			}
			goto out;
		}

		if (ev->join_result == CJ_RES_MASTER_TRANSFER) {
			/* FIXME: This code is tricky, but Sheepdog assumes that */
			/* nr_nodes = 1 when join_result = MASTER_TRANSFER... */
			ev->nr_nodes = 1;
			ev->nodes[0] = this_node;
			ev->pids[0] = getpid();

			shm_queue_set_chksum();
		}

		lhdlrs.join_handler(&ev->sender, ev->nodes, ev->nr_nodes,
				    ev->join_result, ev->buf);
		break;
	case EVENT_LEAVE:
		lhdlrs.leave_handler(&ev->sender, ev->nodes, ev->nr_nodes);
		break;
	case EVENT_NOTIFY:
		if (ev->blocked) {
			if (node_cmp(&ev->sender, &this_node) == 0) {
				if (!ev->callbacked) {
					queue_work(local_block_wq, &work);

					ev->callbacked = 1;
				}
			}
			goto out;
		}

		lhdlrs.notify_handler(&ev->sender, ev->buf, ev->buf_len);
		break;
	}

	shm_queue_pop();
out:
	shm_queue_unlock();

	return 0;
}