/* * 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; }
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; }