/* * Execute a cluster operation by letting the cluster driver send it to all * nodes in the cluster. * * Must run in the main thread as it access unlocked state like * sys->pending_list. */ void queue_cluster_request(struct request *req) { eprintf("%s (%p)\n", op_name(req->op), req); if (has_process_work(req->op)) { list_add_tail(&req->pending_list, &sys->pending_list); sys->cdrv->block(); } else { struct vdi_op_message *msg; size_t size; msg = prepare_cluster_msg(req, &size); if (!msg) return; list_add_tail(&req->pending_list, &sys->pending_list); msg->rsp.result = SD_RES_SUCCESS; sys->cdrv->notify(msg, size); free(msg); } }
void do_cluster_request(struct work *work) { struct request *req = container_of(work, struct request, work); struct sd_req *hdr = (struct sd_req *)&req->rq; struct vdi_op_message *msg; size_t size; eprintf("%p %x\n", req, hdr->opcode); if (has_process_main(req->op)) size = sizeof(*msg) + hdr->data_length; else size = sizeof(*msg); msg = zalloc(size); if (!msg) { eprintf("failed to allocate memory\n"); return; } msg->req = *((struct sd_vdi_req *)&req->rq); msg->rsp = *((struct sd_vdi_rsp *)&req->rp); if (has_process_main(req->op)) memcpy(msg->data, req->data, hdr->data_length); list_add_tail(&req->pending_list, &sys->pending_list); if (has_process_work(req->op)) sys->cdrv->notify(msg, size, do_cluster_op); else { msg->rsp.result = SD_RES_SUCCESS; sys->cdrv->notify(msg, size, NULL); } free(msg); }