static int do_nodes_remove(struct hotplug_context *ctx) { struct rpc_desc *desc; krgnodemask_t nodes; kerrighed_node_t node; char *page; int ret; ret = hotplug_start_request(ctx); if (ret) return ret; ret = check_remove_req(ctx); if (ret) goto err_finish; ret = -ENOMEM; page = (char *)__get_free_page(GFP_KERNEL); if (!page) goto err_finish; ret = krgnodelist_scnprintf(page, PAGE_SIZE, ctx->node_set.v); BUG_ON(ret >= PAGE_SIZE); printk("kerrighed: Removing nodes %s ...\n", page); free_page((unsigned long)page); ret = -ENOMEM; krgnodes_copy(nodes, krgnode_online_map); desc = rpc_begin_m(NODE_REMOVE, ctx->ns->rpc_comm, &nodes); if (!desc) goto err_warning; ret = rpc_pack_type(desc, ctx->node_set); if (ret) { rpc_end(desc, 0); goto err_warning; } ret = 0; for_each_krgnode_mask(node, nodes) rpc_unpack_type_from(desc, node, ret); hotplug_finish_request(ctx); rpc_pack_type(desc, ret); rpc_end(desc, 0); printk("kerrighed: Removing nodes succeeded.\n"); out: return ret; err_warning: printk(KERN_ERR "kerrighed: Removing nodes failed! err=%d\n", ret); err_finish: hotplug_finish_request(ctx); goto out; }
inline void do_krgrpc_handler(struct rpc_desc* desc, int thread_pool_id){ struct __rpc_synchro* __synchro; kerrighed_node_t client; struct waiting_desc *wd; BUG_ON(desc->type != RPC_RQ_SRV); __synchro = desc->__synchro; if(__synchro) __rpc_synchro_get(__synchro); continue_in_synchro: client = desc->client; BUG_ON(!desc->desc_recv[0]); if(test_bit(desc->rpcid, rpc_mask)){ printk("need to move current desc in the waiting_desc queue\n"); BUG(); }; /* Deliver immediately rpc_signals sent before first client's pack() */ rpc_signal_deliver_pending(desc, desc->desc_recv[0]); rpc_handlers[desc->service->handler](desc); BUG_ON(signal_pending(current)); rpc_end(desc, 0); if(__synchro){ // check pending_work in the synchro spin_lock_bh(&__synchro->lock); if(!list_empty(&__synchro->list_waiting_head)){ wd = list_entry(__synchro->list_waiting_head.next, struct waiting_desc, list_waiting_desc); list_del(&wd->list_waiting_desc); spin_unlock_bh(&__synchro->lock); rpc_desc_put(wd->desc); desc = wd->desc; desc->thread = current; desc->state = RPC_STATE_RUN; kfree(wd); goto continue_in_synchro; }else{
long get_appid_from_pid(pid_t pid) { struct rpc_desc *desc; kerrighed_node_t n = KERRIGHED_NODE_ID_NONE; struct getappid_request_msg msg; long app_id; int err = 0; /* lock the task to be sure it does not exit */ n = krg_lock_pid_location(pid); if (n == KERRIGHED_NODE_ID_NONE) return -ESRCH; /* the task is local */ if (n == kerrighed_node_id) { app_id = __get_appid_from_local_pid(pid); if (app_id < 0) err = app_id; goto out_unlock; } err = -ENOMEM; msg.requester = kerrighed_node_id; msg.pid = pid; desc = rpc_begin(APP_REMOTE_CHKPT, n); if (!desc) goto out_unlock; err = rpc_pack_type(desc, msg); if (err) goto err; err = pack_creds(desc, current_cred()); if (err) goto err; err = rpc_unpack_type(desc, app_id); if (err) goto err; out_end: rpc_end(desc, 0); out_unlock: krg_unlock_pid_location(pid); if (err) return err; return app_id; err: rpc_cancel(desc); goto out_end; }
int cluster_barrier(struct cluster_barrier *barrier, krgnodemask_t *nodes, kerrighed_node_t master) { struct cluster_barrier_core *core_bar; struct cluster_barrier_id id; struct rpc_desc *desc; int err = 0; BUG_ON (!__krgnode_isset(kerrighed_node_id, nodes)); BUG_ON (!__krgnode_isset(master, nodes)); spin_lock(&barrier->lock); barrier->id.toggle = (barrier->id.toggle + 1) % 2; id = barrier->id; core_bar = &barrier->core[id.toggle]; if (core_bar->in_barrier) err = -EBUSY; core_bar->in_barrier = 1; spin_unlock(&barrier->lock); if (err) return err; desc = rpc_begin(RPC_ENTER_BARRIER, master); rpc_pack_type (desc, id); rpc_pack(desc, 0, nodes, sizeof(krgnodemask_t)); rpc_end(desc, 0); /* Wait for the barrier to complete */ wait_event (core_bar->waiting_tsk, (core_bar->in_barrier == 0)); return 0; }