/** Export an MM struct * @author Renaud Lottiaux * * @param buffer Buffer to export object data in. * @param obj_entry Object entry of the object to export. */ int mm_export_object (struct rpc_desc *desc, struct kddm_set *set, struct kddm_obj *obj_entry, objid_t objid, int flags) { struct mm_struct *mm; krgsyms_val_t unmap_id, get_unmap_id; mm = obj_entry->object; krgnode_set (desc->client, mm->copyset); rpc_pack(desc, 0, &mm->mm_id, sizeof(unique_id_t)); rpc_pack(desc, 0, &mm->anon_vma_kddm_id, sizeof(unique_id_t)); rpc_pack(desc, 0, &mm->context.vdso, sizeof(void*)); rpc_pack(desc, 0, &mm->copyset, sizeof(krgnodemask_t)); get_unmap_id = krgsyms_export(mm->get_unmapped_area); BUG_ON(mm->get_unmapped_area && get_unmap_id == KRGSYMS_UNDEF); rpc_pack_type(desc, get_unmap_id); unmap_id = krgsyms_export(mm->unmap_area); BUG_ON(mm->unmap_area && unmap_id == KRGSYMS_UNDEF); rpc_pack_type(desc, unmap_id); return 0; }
int __send_faf_file_desc(struct rpc_desc *desc, struct file *file) { int r, fdesc_size; void *fdesc; BUG_ON(!file->f_objid); BUG_ON(!(file->f_flags & (O_FAF_SRV|O_FAF_CLT))); r = get_faf_file_krg_desc(file, &fdesc, &fdesc_size); if (r) goto out; r = rpc_pack_type(desc, file->f_objid); if (r) goto out_free_fdesc; r = rpc_pack_type(desc, fdesc_size); if (r) goto out_free_fdesc; r = rpc_pack(desc, 0, fdesc, fdesc_size); if (r) goto out_free_fdesc; out_free_fdesc: kfree(fdesc); out: return r; }
void rpc_handler_kthread_int(struct rpc_desc* desc){ int res; int id; int err; struct rpc_data rpc_data; err = rpc_unpack(desc, RPC_FLAGS_NOCOPY, &rpc_data, 0); if(!err){ id = rpc_pack(desc, RPC_FLAGS_LATER, &res, sizeof(res)); res = ((rpc_handler_int_t)desc->service->h)(desc, rpc_data.data, rpc_data.size); rpc_free_buffer(&rpc_data); rpc_wait_pack(desc, id); }else{ printk("unexpected event\n"); BUG(); }; };
static void rpc_pingpong_handler (struct rpc_desc *rpc_desc, void *data, size_t size){ unsigned long l = *(unsigned long*)data; l++; rpc_pack(rpc_desc, 0, &l, sizeof(l)); };
int rpc_send(nw_ses *ses, rpc_pkg *pkg) { void *data; uint32_t size; int ret = rpc_pack(pkg, &data, &size); if (ret < 0) return ret; return nw_ses_send(ses, data, size); }
int main(int argc, char *argv[]) { if (argc != 5) { error(1, errno, "usage: %s host port cmd data", argv[0]); } int sockfd = socket(AF_INET, SOCK_DGRAM, 0); if (sockfd < 0) { error(1, errno, "create socket fail"); } struct sockaddr_in addr; memset(&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; if (inet_aton(argv[1], &addr.sin_addr) == 0) { error(1, errno, "ip error"); } addr.sin_port = htons(atoi(argv[2])); rpc_pkg req; memset(&req, 0, sizeof(req)); req.command = strtoul(argv[3], NULL, 0); req.pkg_type = RPC_PKG_TYPE_REQUEST; req.body = argv[4]; req.body_size = strlen(argv[4]); void *data; uint32_t data_size; rpc_pack(&req, &data, &data_size); int ret = sendto(sockfd, data, data_size, 0, (struct sockaddr *)&addr, sizeof(addr)); if (ret < 0) error(1, errno, "send error"); char buf[1024 * 1024]; ret = recvfrom(sockfd, buf, sizeof(buf), 0, NULL, NULL); if (ret < 0) { error(1, errno, "recvfrom fail"); } ret = rpc_decode(NULL, buf, ret); if (ret <= 0) { error(1, errno, "decode fail"); } struct rpc_pkg rsp; memcpy(&rsp, buf, RPC_PKG_HEAD_SIZE); rsp.ext = buf + RPC_PKG_HEAD_SIZE; rsp.body = rsp.ext + rsp.ext_size; sds reply = sdsnewlen(rsp.body, rsp.body_size); printf("%s\n", reply); sdsfree(reply); return 0; }
/** Request an IO linker to export data from an object. * @author Renaud Lottiaux * * @param set Kddm Set the object belong to. * @param obj_entry Object entry to export data from. * @param desc RPC descriptor to export data on. */ int kddm_io_export_object (struct rpc_desc *desc, struct kddm_set *set, struct kddm_obj *obj_entry, objid_t objid, int flags) { struct iolinker_struct *io = set->iolinker; int res; if (io && io->export_object) res = io->export_object(desc, set, obj_entry, objid, flags); else res = rpc_pack(desc, 0, obj_entry->object, set->obj_size); return res; }
int handle_faf_getpeername (struct rpc_desc* desc, void *msgIn, size_t size) { struct faf_bind_msg *msg = msgIn; struct prev_root prev_root; int r; unpack_root(desc, &prev_root); r = sys_getpeername(msg->server_fd, (struct sockaddr *)&msg->sa, &msg->addrlen); rpc_pack_type(desc, msg->addrlen); rpc_pack(desc, 0, &msg->sa, msg->addrlen); chroot_to_prev_root(&prev_root); return r; }
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; }
/** Handler for reading in a FAF open file. * @author Renaud Lottiaux, Matthieu Fertré * * @param from Node sending the request * @param msgIn Request message */ void handle_faf_read(struct rpc_desc* desc, void *msgIn, size_t size) { struct faf_rw_msg *msg = msgIn; struct file *file = NULL; char *buf = NULL; long buf_size = PAGE_SIZE; ssize_t to_read, r; loff_t fpos; int err; err = remote_sleep_prepare(desc); if (err) { rpc_cancel(desc); return; } to_read = msg->count; fpos = msg->pos; r = -ENOMEM; buf = kmalloc(PAGE_SIZE, GFP_KERNEL); if (!buf) goto error; file = fget(msg->server_fd); while (to_read > 0) { if (to_read < PAGE_SIZE) buf_size = to_read; r = vfs_read(file, buf, buf_size, &fpos); if (r > 0) { err = rpc_pack_type(desc, r); if (err) goto cancel; err = rpc_pack(desc, 0, buf, r); if (err) goto cancel; } /* * Check if we have reach the end of the file * or if there is an error */ if (r < buf_size) break; to_read -= r; } error: /* * Pack the end of transmission mark (0) * or the error returned by vfs_read() */ if (r > 0) r = 0; err = rpc_pack_type(desc, r); if (err) goto cancel; /* send the updated file position */ err = rpc_pack_type(desc, fpos); if (err) goto cancel; out: if (buf) kfree(buf); if (file) fput(file); remote_sleep_finish(); return; cancel: rpc_cancel(desc); goto out; }
void handle_faf_accept (struct rpc_desc *desc, void *msgIn, size_t size) { struct faf_bind_msg *msg = msgIn; int err, r; struct file *file; r = remote_sleep_prepare(desc); if (r) goto err_cancel; r = sys_accept(msg->server_fd, (struct sockaddr *)&msg->sa, &msg->addrlen); remote_sleep_finish(); err = rpc_pack_type(desc, r); if (err) goto err_close_file; if (r < 0) return; file = fcheck_files(current->files, r); if (!file->f_objid) { err = create_kddm_file_object(file); if (err) goto err_close_file; } file->f_flags |= O_FAF_SRV; file->f_faf_srv_index = r; /* Increment the DVFS count for the client node */ get_dvfs_file(r, file->f_objid); err = rpc_pack_type(desc, msg->addrlen); if (err) goto err_close_faf_file; err = rpc_pack(desc, 0, &msg->sa, msg->addrlen); if (err) goto err_close_faf_file; err = __send_faf_file_desc(desc, file); if (err) goto err_close_faf_file; err = rpc_unpack_type(desc, r); if (err) goto err_close_faf_file; out: return; err_cancel: rpc_cancel(desc); goto out; err_close_faf_file: /* The client couldn't setup a FAF client file. */ put_dvfs_file(file->f_faf_srv_index, file); check_close_faf_srv_file(file); goto err_cancel; err_close_file: if (r >= 0) sys_close(r); goto err_cancel; }
/** Handler for d_path in a FAF open file. * @author Renaud Lottiaux * * @param from Node sending the request * @param msgIn Request message */ void handle_faf_d_path (struct rpc_desc* desc, void *msgIn, size_t size) { struct faf_d_path_msg *msg = msgIn; char *buff, *file_name = NULL; struct file *file; struct prev_root prev_root; const struct cred *old_cred; bool deleted = false; int len; int err; old_cred = unpack_override_creds(desc); if (IS_ERR(old_cred)) { rpc_cancel(desc); return; } err = unpack_root(desc, &prev_root); if (err) { revert_creds(old_cred); rpc_cancel(desc); return; } buff = kmalloc (msg->count, GFP_KERNEL); file = fcheck_files (current->files, msg->server_fd); /* Remote caller holds a reference so it can't disappear. */ BUG_ON(!file); if (msg->deleted) file_name = d_path_check(&file->f_path, buff, msg->count, &deleted); else file_name = d_path(&file->f_path, buff, msg->count); if (IS_ERR(file_name)) len = PTR_ERR(file_name); else len = strlen(file_name) + 1; err = rpc_pack_type(desc, len); if (err) goto err_cancel; if (len >= 0) { err = rpc_pack(desc, 0, file_name, len); if (err) goto err_cancel; if (msg->deleted) { err = rpc_pack_type(desc, deleted); if (err) goto err_cancel; } } out: kfree (buff); chroot_to_prev_root(&prev_root); revert_creds(old_cred); return; err_cancel: rpc_cancel(desc); goto out; }