Exemplo n.º 1
0
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;
}
Exemplo n.º 2
0
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);
}
Exemplo n.º 3
0
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;
}
Exemplo n.º 4
0
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;
}
Exemplo n.º 5
0
/** 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);
}
Exemplo n.º 6
0
/** 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;
}
Exemplo n.º 7
0
/* 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);
}
Exemplo n.º 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;
}
Exemplo n.º 9
0
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;
}
Exemplo n.º 10
0
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;
}
Exemplo n.º 11
0
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;
}
Exemplo n.º 12
0
/** 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);
}
Exemplo n.º 13
0
/** 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);
}
Exemplo n.º 14
0
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;
}
Exemplo n.º 15
0
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);
}
Exemplo n.º 16
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;
}
Exemplo n.º 17
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;
}
Exemplo n.º 18
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;
}
Exemplo n.º 19
0
/** 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;
}