static void do_local_node_remove(struct rpc_desc *desc, struct hotplug_context *ctx) { struct rpc_communicator *comm = ctx->ns->rpc_comm; krgnodemask_t prev_online, new_online; int ret; SET_KERRIGHED_NODE_FLAGS(KRGFLAGS_STOPPING); printk("do_local_node_remove\n"); krgnodes_copy(prev_online, krgnode_online_map); krgnodes_andnot(new_online, krgnode_online_map, ctx->node_set.v); atomic_set(&nr_to_wait, krgnodes_weight(new_online)); printk("...notify local\n"); hotplug_remove_notify(ctx, HOTPLUG_NOTIFY_REMOVE_LOCAL); krgnodes_copy(new_online, krgnode_online_map); printk("...notify_distant\n"); hotplug_remove_notify(ctx, HOTPLUG_NOTIFY_REMOVE_DISTANT); printk("...confirm\n"); rpc_sync_m(NODE_REMOVE_CONFIRM, comm, &new_online, &ctx->node_set, sizeof(ctx->node_set)); printk("...wait ack\n"); wait_event(all_removed_wqh, atomic_read(&nr_to_wait) == 0); rpc_disable_all(); rpc_enable(HOTPLUG_FINISH_REQ); ret = 0; rpc_pack_type(desc, ret); rpc_unpack_type(desc, ret); rpc_disable(HOTPLUG_FINISH_REQ); CLEAR_KERRIGHED_NODE_FLAGS(KRGFLAGS_RUNNING); CLEAR_KERRIGHED_CLUSTER_FLAGS(KRGFLAGS_RUNNING); clusters_status[kerrighed_subsession_id] = CLUSTER_UNDEF; down_write(&kerrighed_init_sem); hooks_stop(); up_write(&kerrighed_init_sem); rpc_close_mask(comm, &prev_online); rpc_communicator_put(comm); ctx->ns->rpc_comm = NULL; CLEAR_KERRIGHED_NODE_FLAGS(KRGFLAGS_STOPPING); kerrighed_subsession_id = -1; rpc_enable(CLUSTER_START); }
static int barrier_notification(struct notifier_block *nb, hotplug_event_t event, void *data) { switch(event){ case HOTPLUG_NOTIFY_ADD: rpc_enable(RPC_ENTER_BARRIER); rpc_enable(RPC_EXIT_BARRIER); break; case HOTPLUG_NOTIFY_REMOVE: /* TODO */ break; case HOTPLUG_NOTIFY_FAIL: /* TODO */ break; default: BUG(); } return NOTIFY_OK; }