void handle_faf_sendmsg(struct rpc_desc *desc, void *msgIn, size_t size) { struct faf_sendmsg_msg *msg = msgIn; ssize_t r; int err; struct msghdr msghdr; err = recv_msghdr(desc, &msghdr, msg->total_len, 0); if (err) { rpc_cancel(desc); return; } err = remote_sleep_prepare(desc); if (err) goto cancel; r = sys_sendmsg (msg->server_fd, &msghdr, msg->flags); remote_sleep_finish(); err = rpc_pack_type(desc, r); if (err) goto cancel; out_free: free_msghdr(&msghdr); return; cancel: rpc_cancel(desc); goto out_free; }
static void handle_faf_poll_wait(struct rpc_desc *desc, void *_msg, size_t size) { struct faf_poll_wait_msg *msg = _msg; struct file *file; unsigned int revents; int err, res = 0; if (msg->wait) { res = faf_polled_fd_add(desc->client, msg->server_fd, msg->objid); err = rpc_pack_type(desc, res); if (err) goto err; } file = fget(msg->server_fd); BUG_ON(!file); revents = file->f_op->poll(file, NULL); fput(file); err = rpc_pack_type(desc, revents); if (err) goto err; return; err: if (msg->wait && !res) faf_polled_fd_remove(desc->client, msg->server_fd, msg->objid); rpc_cancel(desc); }
static int remote_get_pid_cap(pid_t pid, kernel_krg_cap_t *cap) { struct rpc_desc *desc; int err = -ESRCH; int res; desc = krg_remote_syscall_begin(PROC_GET_PID_CAP, pid, NULL, 0); if (IS_ERR(desc)) { err = PTR_ERR(desc); goto out; } err = rpc_unpack_type(desc, res); if (err) goto err_cancel; if (res) { err = res; goto out_end; } err = rpc_unpack_type(desc, *cap); if (err) goto err_cancel; out_end: krg_remote_syscall_end(desc, pid); out: return err; err_cancel: rpc_cancel(desc); if (err > 0) err = -EPIPE; goto out_end; }
static int handle_get_pid_cap(struct rpc_desc *desc, void *_msg, size_t size) { struct pid *pid; kernel_krg_cap_t cap; const struct cred *old_cred; int ret; pid = krg_handle_remote_syscall_begin(desc, _msg, size, NULL, &old_cred); if (IS_ERR(pid)) { ret = PTR_ERR(pid); goto out; } ret = krg_get_cap(pid_task(pid, PIDTYPE_PID), &cap); if (ret) goto out_end; ret = rpc_pack_type(desc, cap); if (ret) goto err_cancel; out_end: krg_handle_remote_syscall_end(pid, old_cred); out: return ret; err_cancel: rpc_cancel(desc); goto out_end; }
/** Handler for locking in a FAF open file. * @author Renaud Lottiaux * * @param from Node sending the request * @param msgIn Request message */ void handle_faf_flock(struct rpc_desc *desc, void *msgIn, size_t size) { struct faf_ctl_msg *msg = msgIn; const struct cred *old_cred; long r = -EINVAL; int err; old_cred = unpack_override_creds(desc); if (IS_ERR(old_cred)) goto cancel; r = remote_sleep_prepare(desc); if (r) { revert_creds(old_cred); goto cancel; } r = sys_flock (msg->server_fd, msg->cmd); remote_sleep_finish(); revert_creds(old_cred); err = rpc_pack_type(desc, r); if (err) goto cancel; return; cancel: rpc_cancel(desc); }
/** Handler for doing an IOCTL in a FAF open file. * @author Renaud Lottiaux * * @param from Node sending the request * @param msgIn Request message */ void handle_faf_ioctl(struct rpc_desc *desc, void *msgIn, size_t size) { struct faf_ctl_msg *msg = msgIn; struct prev_root prev_root; const struct cred *old_cred; long r; int err; err = unpack_context(desc, &prev_root, &old_cred); if (err) { rpc_cancel(desc); return; } err = remote_sleep_prepare(desc); if (err) goto out_err; err = prepare_ruaccess(desc); if (err) goto out_sleep_finish; r = sys_ioctl(msg->server_fd, msg->cmd, msg->arg); err = cleanup_ruaccess(desc); if (err) goto out_sleep_finish; err = rpc_pack_type(desc, r); out_sleep_finish: remote_sleep_finish(); if (err) goto out_err; out: restore_context(&prev_root, old_cred); return; out_err: rpc_cancel(desc); goto out; }
/* cluster receive the confirmation about the remove operation */ static void handle_node_remove_confirm(struct rpc_desc *desc, void *data, size_t size) { int dummy; BUG_ON(desc->client == kerrighed_node_id); hotplug_remove_notify((void*)&desc->client, HOTPLUG_NOTIFY_REMOVE_ACK); if (rpc_pack_type(desc, dummy)) rpc_cancel(desc); if (atomic_dec_and_test(&nr_to_wait)) wake_up(&all_removed_wqh); printk("Kerrighed: node %d removed\n", desc->client); }
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; }
void handle_faf_setsockopt (struct rpc_desc *desc, void *msgIn, size_t size) { struct faf_setsockopt_msg *msg = msgIn; struct prev_root prev_root; const struct cred *old_cred; int r, err; err = unpack_context(desc, &prev_root, &old_cred); if (err) { rpc_cancel(desc); return; } err = prepare_ruaccess(desc); if (err) goto out_err; r = sys_setsockopt(msg->server_fd, msg->level, msg->optname, msg->optval, msg->optlen); err = cleanup_ruaccess(desc); if (err) goto out_err; err = rpc_pack_type(desc, r); if (err) goto out_err; exit: restore_context(&prev_root, old_cred); return; out_err: rpc_cancel(desc); if (err > 0) err = -ENOMEM; r = err; goto exit; }
void handle_faf_connect(struct rpc_desc *desc, void *msgIn, size_t size) { struct faf_bind_msg *msg = msgIn; struct prev_root prev_root; const struct cred *old_cred; int r, err; r = unpack_context(desc, &prev_root, &old_cred); if (r) { rpc_cancel(desc); return; } r = remote_sleep_prepare(desc); if (r) goto cancel; r = sys_connect(msg->server_fd, (struct sockaddr *)&msg->sa, msg->addrlen); remote_sleep_finish(); err = rpc_pack_type(desc, r); if (err) goto cancel; out: restore_context(&prev_root, old_cred); return; cancel: rpc_cancel(desc); goto out; }
static void handle_faf_readv(struct rpc_desc *desc, void *__msg, size_t size) { struct faf_rw_msg *msg = __msg; struct faf_rw_ret ret; struct file *file; struct iovec *iov; int iovcnt, err; err = alloc_iov(&iov, &iovcnt, msg->count); if (err) { ret.ret = err; iov = NULL; } err = remote_sleep_prepare(desc); if (err) goto cancel; ret.pos = msg->pos; if (iov) { file = fget(msg->server_fd); ret.ret = vfs_readv(file, iov, iovcnt, &ret.pos); fput(file); } remote_sleep_finish(); err = rpc_pack_type(desc, ret); if (err) goto cancel; if (ret.ret <= 0) goto out_free; err = send_iov(desc, iov, iovcnt, ret.ret, 0); if (err) goto cancel; out_free: if (iov) free_iov(iov, iovcnt); return; cancel: rpc_cancel(desc); goto out_free; }
/** Handler for doing an FCNTL64 in a FAF open file. * @author Renaud Lottiaux * * @param from Node sending the request * @param msgIn Request message */ void handle_faf_fcntl64 (struct rpc_desc* desc, void *msgIn, size_t size) { struct faf_ctl_msg *msg = msgIn; const struct cred *old_cred; unsigned long arg; long r; int err; if (msg->cmd == F_GETLK64 || msg->cmd == F_SETLK64 || msg->cmd == F_SETLKW64) arg = (unsigned long) &msg->flock64; else arg = msg->arg; old_cred = unpack_override_creds(desc); if (IS_ERR(old_cred)) goto cancel; err = remote_sleep_prepare(desc); if (err) { revert_creds(old_cred); goto cancel; } r = sys_fcntl64 (msg->server_fd, msg->cmd, arg); remote_sleep_finish(); revert_creds(old_cred); err = rpc_pack_type(desc, r); if (unlikely(err)) goto cancel; if (!r && msg->cmd == F_GETLK64) { err = rpc_pack_type(desc, msg->flock64); if (unlikely(err)) goto cancel; } return; cancel: rpc_cancel(desc); }
/** Handler for doing an FSTATFS in a FAF open file. * @author Matthieu Fertré * * @param from Node sending the request * @param msgIn Request message */ static void handle_faf_fstatfs(struct rpc_desc* desc, void *msgIn, size_t size) { struct statfs statbuf; struct faf_statfs_msg *msg = msgIn; long r; int err_rpc; r = sys_fstatfs(msg->server_fd, &statbuf); err_rpc = rpc_pack_type(desc, r); if (err_rpc) goto err_rpc; if (!r) err_rpc = rpc_pack_type(desc, statbuf); err_rpc: if (err_rpc) rpc_cancel(desc); }
int handle_faf_bind (struct rpc_desc* desc, void *msgIn, size_t size) { struct faf_bind_msg *msg = msgIn; struct prev_root prev_root; const struct cred *old_cred; int r; r = unpack_context(desc, &prev_root, &old_cred); if (r) { rpc_cancel(desc); return r; } r = sys_bind(msg->server_fd, (struct sockaddr *)&msg->sa, msg->addrlen); restore_context(&prev_root, old_cred); return r; }
static void handle_get_appid_from_pid(struct rpc_desc *desc, void *_msg, size_t size) { struct getappid_request_msg *msg = _msg; long app_id; const struct cred *old_cred; int err; old_cred = unpack_override_creds(desc); if (IS_ERR(old_cred)) { err = PTR_ERR(old_cred); goto out; } app_id = __get_appid_from_local_pid(msg->pid); revert_creds(old_cred); err = rpc_pack_type(desc, app_id); out: if (err) rpc_cancel(desc); }
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 writing in a FAF open file. * @author Renaud Lottiaux, Matthieu Fertré * * @param from Node sending the request * @param msgIn Request message */ void handle_faf_write(struct rpc_desc* desc, void *msgIn, size_t size) { struct faf_rw_msg *msg = msgIn; struct file *file = NULL; long to_recv; char *buf = NULL; ssize_t buf_size = PAGE_SIZE; ssize_t r, nr_received = -ENOMEM; loff_t fpos; int err; r = remote_sleep_prepare(desc); if (r) { rpc_cancel(desc); return; } to_recv = msg->count; fpos = msg->pos; buf = kmalloc(PAGE_SIZE, GFP_KERNEL); if (!buf) goto error; nr_received = 0; file = fget(msg->server_fd); while (to_recv > 0) { err = rpc_unpack_type(desc, buf_size); if (err) goto cancel; /* copy_from_user has failed on the other side */ if (buf_size < 0) { nr_received = buf_size; break; } err = rpc_unpack(desc, 0, buf, buf_size); if (err) goto cancel; r = vfs_write(file, buf, buf_size, &fpos); /* The last write failed. Break the write sequence */ if (r < 0) { nr_received = r; break; } nr_received += r; to_recv -= buf_size; } error: err = rpc_pack_type(desc, nr_received); 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; }
/** 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; }
/** 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; }