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; }
/** Import an MM struct * @author Renaud Lottiaux * * @param obj_entry Object entry of the object to import. * @param _buffer Data to import in the object. */ int mm_import_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; struct kddm_set *set; unique_id_t mm_id, kddm_id; void *context_vdso; int r; mm = obj_entry->object; r = rpc_unpack (desc, 0, &mm_id, sizeof(unique_id_t)); if (r) return r; r = rpc_unpack (desc, 0, &kddm_id, sizeof(unique_id_t)); if (r) return r; r = rpc_unpack (desc, 0, &context_vdso, sizeof(void*)); if (r) return r; if (mm == NULL) { /* First import */ set = _find_get_kddm_set(kddm_def_ns, kddm_id); BUG_ON (set == NULL); mm = set->obj_set; mm->mm_id = mm_id; atomic_inc(&mm->mm_users); obj_entry->object = mm; put_kddm_set(set); mm->context.vdso = context_vdso; } r = rpc_unpack(desc, 0, &mm->copyset, sizeof(krgnodemask_t)); if (r) return r; r = rpc_unpack_type(desc, get_unmap_id); if (r) return r; mm->get_unmapped_area = krgsyms_import (get_unmap_id); r = rpc_unpack_type(desc, unmap_id); if (r) return r; mm->unmap_area = krgsyms_import (unmap_id); return 0; }
struct file *rcv_faf_file_desc(struct rpc_desc *desc) { int r, first_import; void *fdesc; int fdesc_size; long fobjid; struct dvfs_file_struct *dvfs_file = NULL; struct file *file = NULL; r = rpc_unpack_type(desc, fobjid); if (r) goto error; r = rpc_unpack_type(desc, fdesc_size); if (r) goto error; fdesc = kmalloc(GFP_KERNEL, fdesc_size); if (!fdesc) { r = -ENOMEM; goto error; } r = rpc_unpack(desc, 0, fdesc, fdesc_size); if (r) goto err_free_desc; /* Check if the file struct is already present */ first_import = 0; file = begin_import_dvfs_file(fobjid, &dvfs_file); if (!file) { file = create_faf_file_from_krg_desc(current, fdesc); first_import = 1; } r = end_import_dvfs_file(fobjid, dvfs_file, file, first_import); if (r) goto err_free_desc; err_free_desc: kfree(fdesc); error: if (r) file = ERR_PTR(r); return file; }
static int unpack_path(struct rpc_desc *desc, struct path *path) { char *tmp; int len, err; err = -ENOMEM; tmp = (char *)__get_free_page(GFP_KERNEL); if (!tmp) goto out; err = rpc_unpack_type(desc, len); if (err) goto out_free; err = rpc_unpack(desc, 0, tmp, len); if (err) goto out_free; err = kern_path(tmp, LOOKUP_FOLLOW | LOOKUP_DIRECTORY, path); out_free: free_page((unsigned long)tmp); out: return err; }
int unpack_remote_sleep_res_prepare(struct rpc_desc *desc) { int dummy, err; err = rpc_unpack_type(desc, dummy); if (err > 0) err = -EPIPE; return err; }
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); }
/* * @author Pascal Gallard */ static int pid_import_object(struct rpc_desc *desc, struct kddm_set *set, struct kddm_obj *obj_entry, objid_t objid, int flags) { struct pid_kddm_object *obj = obj_entry->object; return rpc_unpack_type(desc, obj->node_count); }
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; }
/* * @author Pascal Gallard */ static int task_import_object(struct rpc_desc *desc, struct kddm_set *set, struct kddm_obj *obj_entry, objid_t objid, int flags) { struct task_kddm_object *dest = obj_entry->object; struct task_kddm_object src; int retval; retval = rpc_unpack_type(desc, src); if (retval) return retval; write_lock_irq(&tasklist_lock); dest->state = src.state; dest->flags = src.flags; dest->ptrace = src.ptrace; dest->exit_state = src.exit_state; dest->exit_code = src.exit_code; dest->exit_signal = src.exit_signal; dest->node = src.node; dest->self_exec_id = src.self_exec_id; dest->thread_group_empty = src.thread_group_empty; dest->parent = src.parent; dest->parent_node = src.parent_node; dest->real_parent = src.real_parent; dest->real_parent_tgid = src.real_parent_tgid; dest->group_leader = src.group_leader; dest->uid = src.uid; dest->euid = src.euid; dest->egid = src.egid; dest->utime = src.utime; dest->stime = src.stime; dest->dumpable = src.dumpable; write_unlock_irq(&tasklist_lock); return 0; }
static void do_other_node_remove(struct rpc_desc *desc, struct hotplug_context *ctx) { int ret; printk("do_other_node_remove\n"); atomic_set(&nr_to_wait, krgnodes_weight(ctx->node_set.v)); hotplug_remove_notify(ctx, HOTPLUG_NOTIFY_REMOVE_ADVERT); rpc_async_m(NODE_REMOVE_ACK, ctx->ns->rpc_comm, &ctx->node_set.v, NULL, 0); wait_event(all_removed_wqh, atomic_read(&nr_to_wait) == 0); ret = 0; rpc_pack_type(desc, ret); rpc_unpack_type(desc, ret); rpc_close_mask(ctx->ns->rpc_comm, &ctx->node_set.v); }
/** 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; }
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; }