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;
}
Example #4
0
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;
}
Example #5
0
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;
}
Example #6
0
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);
}
Example #7
0
/*
 * @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);
}
Example #8
0
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;
}
Example #9
0
/*
 * @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;
}
Example #10
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);
}
Example #11
0
/** 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;
}
Example #12
0
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;
}