Ejemplo n.º 1
0
static void shm_queue_init(void)
{
	int ret;

	shmfd = open(shmfile, O_CREAT | O_RDWR, 0644);
	if (shmfd < 0)
		panic("cannot open shared file, %s\n", shmfile);

	shm_queue_lock();

	ret = ftruncate(shmfd, sizeof(*shm_queue));
	assert(ret == 0);

	shm_queue = mmap(0, sizeof(*shm_queue),
			 PROT_READ | PROT_WRITE, MAP_SHARED, shmfd, 0);
	assert(shm_queue != MAP_FAILED);

	if (is_shm_queue_valid())
		event_pos = shm_queue->pos;
	else {
		/* initialize shared memory */
		event_pos = 0;
		ret = ftruncate(shmfd, 0);
		assert(ret == 0);
		ret = ftruncate(shmfd, sizeof(*shm_queue));
		assert(ret == 0);

		shm_queue_set_chksum();
	}

	shm_queue_unlock();
}
Ejemplo n.º 2
0
/*
 * 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;
}
Ejemplo n.º 3
0
static void shm_queue_notify(void)
{
	int i;
	size_t nr;
	pid_t pids[SD_MAX_NODES];

	shm_queue_set_chksum();

	nr = get_nodes(NULL, pids);

	for (i = 0; i < nr; i++)
		kill(pids[i], SIGUSR1);
}
Ejemplo n.º 4
0
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;
}