Exemplo n.º 1
0
static int global_9p_mount(struct fs_mounter* mounter, int16_t fsuid, int16_t fsgid) {	
	int err = 0;
	char mount_buffer[MAX_MOUNT_ROOT_PATH], root_buffer[MAX_MOUNT_ROOT_PATH+6];
	struct nameidata nd;
	get_mount_root(mounter->params.mount_device, fsuid, fsgid, mount_buffer);
	err = path_lookup(mount_buffer, LOOKUP_FOLLOW | LOOKUP_DIRECTORY ,&nd);
	if ( err ) {
		minfo(ERR1, "Failed to lookup path %s: %d. Trying to create", mount_buffer, err);
		err = mk_dir(mount_buffer, 777);
	}
	if ( err ) {
		// TODO: For now, the dirs for mount have to be precreated.. they can be for example
		// auto created via a user-space controller. In kernel, we do not have access to mkdir, right?
		minfo(ERR1, "Failed to lookup path %s: %d. Creation failed.", mount_buffer, err);
		return err;
	}
	sprintf(root_buffer, "%s/root", mount_buffer);
	// TODO: In critical section so that we do not do multiple mounts
	err = path_lookup(root_buffer, LOOKUP_FOLLOW | LOOKUP_DIRECTORY ,&nd);	
	if ( err ) {
		// We've checked that "root"/root does not exist (We assume existence of a root dir in root of fs
		// => 9p is not yet globally mount => mount
		if ( (err = mount_9p_fs(mount_buffer, mounter, fsuid, fsgid)) ) {
			minfo(ERR1, "Mount failed with err %d", err);
			return err;
		}
	}		

	return 0;
}
Exemplo n.º 2
0
/** 
 * This method represents a kernel thread that will eventually
 * become the migrated task. It does following:
 * - waits until signalled, that the guest is ready
 * - picks up the guest task
 * - runs its migration mode handler.
 */
int migrated_task(void *data)
{
	int err = -EINVAL;
	struct completion *guest_ready = (struct completion*) data;

	minfo(INFO1, "Starting new thread for migrating task..");
	if ((err = wait_for_completion_interruptible(guest_ready))) {
		minfo(INFO1, "Received signal guest not ready");
		goto exit0;
	}
	minfo(INFO1, "Stub is ready by now..");
	/* This part simulates when the process didn't pickup
	   the shadow task on time 
	set_current_state(TASK_INTERRUPTIBLE);
	schedule_timeout(5*HZ); 
	minfo(INFO1, "Task has woken up %p", current);
	*/
	if (!current->tcmi.mig_mode_handler) {
		minfo(ERR3, "Missing migration mode handler for guest task!!");
		goto exit0;
	}
	current->tcmi.mig_mode_handler();

	return 0;
	/* error handling */
 exit0:

	return err;
}
Exemplo n.º 3
0
/**
 * \<\<private\>\> Processes a TCMI message m. 
 * The message is desposed afterwords.
 *
 * @param *self - pointer to this migration manager instance
 * @param *m - pointer to a message to be processed
 */
static void tcmi_ccnmigman_process_msg(struct tcmi_migman *self, struct tcmi_msg *m)
{
	struct tcmi_msg *resp;
	int result_code = 0;
	int accepted;
	struct tcmi_authenticate_msg *auth_msg;
	struct tcmi_generic_user_msg *user_msg;

	/* struct tcmi_ccnmigman *self_ccn = TCMI_CCNMIGMAN(self); */
	int err;
	mdbg(INFO4, "Processing message ID");

	switch(tcmi_msg_id(m)) {
	case TCMI_AUTHENTICATE_MSG_ID:
		auth_msg = TCMI_AUTHENTICATE_MSG(m);
		minfo(INFO1, "Authentication message arrived.");
		
		// Inform director that the node was connected 
		err = director_node_connected(kkc_sock_getpeername2(tcmi_migman_sock(self)), tcmi_migman_slot_index(self), tcmi_authenticate_msg_auth_data_size(auth_msg), tcmi_authenticate_msg_auth_data(auth_msg), &accepted);
		// The check for accept is performed only if the director responded, otherwise the call is ignored
		if ( !err && !accepted ) {
			minfo(ERR1, "Director rejected peer connection");
			break;
		}

		self->pen_id = tcmi_authenticate_msg_pen_id(auth_msg);
		self->peer_arch_type = tcmi_authenticate_msg_arch(auth_msg);

		if ( !( resp = tcmi_authenticate_resp_msg_new_tx(tcmi_msg_req_id(m), self->ccn_id, ARCH_CURRENT, result_code, tcmi_ccnman_get_mount_params()) ) ) { 
			mdbg(ERR3, "Error creating response message");
			break;
		}
		if ((err = tcmi_msg_send_anonymous(resp, tcmi_migman_sock(self)))) {
			mdbg(ERR3, "Error sending response message %d", err);
		}
		tcmi_msg_put(resp);
		tcmi_migman_set_state(self, TCMI_MIGMAN_CONNECTED);
		wake_up(&(TCMI_CCNMIGMAN(self)->wq));
		break;
	case TCMI_GENERIC_USER_MSG_ID:
		user_msg = TCMI_GENERIC_USER_MSG(m);
		minfo(INFO1, "User message arrived.");

		err = director_generic_user_message_recv(tcmi_generic_user_msg_node_id(user_msg), 1, tcmi_migman_slot_index(self), tcmi_generic_user_msg_user_data_size(user_msg), tcmi_generic_user_msg_user_data(user_msg));
		if ( err ) {
			mdbg(ERR3, "Error in processing user message %d", err);
		}
		break;
	default:
		minfo(INFO1, "Unexpected message ID %x, no handler available.", 
		      tcmi_msg_id(m));
		break;
	}

	/* release the message */
	tcmi_msg_put(m);

}
Exemplo n.º 4
0
int
main (void)
{
  char *p;

  minfo();
  p = malloc(10);
  free(p);
  minfo();

  return EXIT_SUCCESS;
}
Exemplo n.º 5
0
/** 
 * \<\<public\>\> Releases the instance. 
 * - calls custom free method for a specific task
 * - destroys all ctlfs files, directories, symlinks
 * - destroys the transaction slot vector
 * - empties the message queue
 * - empties the method queue
 * - releases the execve context (execve filename, argv, envp) 
 *
 * @param *self - pointer to this task instance
 */
void tcmi_task_put(struct tcmi_task *self)
{
	/* Used for destruction of messages and methods. */
	struct tcmi_msg *m;
	struct tcmi_method_wrapper *w;

	if (self && atomic_dec_and_test(&self->ref_count)) {
		mdbg(INFO4, "Destroying TCMI task PID=%d, %p", 
		     tcmi_task_local_pid(self), self);
		/* instance specific free method */
		if (self->ops->free)
			self->ops->free(self);
		kkc_sock_put(self->sock);
		/* destroy all ctlfs entries */
		tcmi_ctlfs_file_unregister(self->f_remote_pid);
		tcmi_ctlfs_entry_put(self->f_remote_pid);
		tcmi_ctlfs_entry_put(self->s_migman);
		tcmi_ctlfs_entry_put(self->d_task);
		tcmi_ctlfs_entry_put(self->f_remote_pid_rev);

		if (!tcmi_slotvec_empty(self->transactions))
			mdbg(WARN2, "Task %d, destroying non-empty transactions slotvector!!",
			     self->local_pid);
		tcmi_slotvec_put(self->transactions);

		/* destroy remaining messages in the queue. */
		while (!tcmi_queue_empty(&self->msg_queue)) {
			tcmi_queue_remove_entry(&self->msg_queue, m, node);
			mdbg(INFO3, "Task %d, destroying message %x",
			     tcmi_task_local_pid(self), tcmi_msg_id(m));
			tcmi_msg_put(m);
		}
		/* destroy remaining methods in the queue. */
		while (!tcmi_queue_empty(&self->method_queue)) {
			tcmi_queue_remove_entry(&self->method_queue, w, node);
			mdbg(INFO3, "Task %d, destroying method wrapper %p",
			     tcmi_task_local_pid(self), w);
			tcmi_method_wrapper_put(w);
		}
		minfo(INFO3, "Releasing execve context");
		tcmi_task_release_execve_context(self);
		minfo(INFO3, "Done..");
		tcmi_migman_remove_task(self->migman, self);
		minfo(INFO3, "Removed from migman tasks done");
		tcmi_migman_put(self->migman);
		kfree(self);
	}
}
Exemplo n.º 6
0
/** \<\<public\>\> Close proxyfile
 * @param *self - pointer to this file instance
 *
 * @return zero on succes
 * */
int proxyfs_proxy_file_close(struct proxyfs_proxy_file_t *self)
{
	struct proxyfs_msg *msg;
	struct proxyfs_msg *msg_resp;
	long rtn = -ERESTARTSYS;
	u_int32_t exitting = current->flags & PF_EXITING;

	mdbg(INFO2, "Close proxy file requested. Ident: %lu Exitting: %d", proxyfs_file_get_file_ident(PROXYFS_FILE(self)), exitting );
	
	// We have to wait for a write buffer empty event..
	// TODO: however, if the peer connection is broken, this will never happen, and the close method will block.. what to do? Likely we should wait with some long timeout and then just break (or at least recheck connection)
	if( proxyfs_proxy_file_wait_interruptible(self, PROXYFS_FILE_ALL_WRITTEN ) == 0 ) {
		minfo(ERR2, "Closing of ident: %lu failed. Not all written", proxyfs_file_get_file_ident(PROXYFS_FILE(self)));
		return -ERESTARTSYS;
	}

	msg = proxyfs_msg_new(MSG_CLOSE, proxyfs_file_get_file_ident(PROXYFS_FILE(self)), sizeof(exitting), &exitting); 
	if(msg != NULL){
		msg_resp = proxyfs_client_do_syscall(self->task, self, msg);
		// What the fck?????
		if( msg_resp == (void*)MSG_CLOSE_RESP )
			rtn = 0;
	}

  
	if ( rtn != 0 && proxyfs_peer_get_state(PROXYFS_FILE(self)->peer) != PEER_CONNECTED) {
	      // Even if our remote syscall has failed, we have to pretend it succeded as the peer is no longer connected and there is no chance of further close success
	      rtn = 0;
	}

	mdbg(INFO2, "Close proxy file request DONE, Res: %ld", rtn);

	return rtn;
}
Exemplo n.º 7
0
/**
 * \<\<public\>\> Root entry accessor. If the filesystem has not been
 * activated yet, a kernel mount is performed. The kernel mount in
 * turn ensures instantiation of the root directory. A user might have
 * already mounted the filesystem from userspace. This is not a
 * problem as we allow only one instance of the filesystem in
 * memory(enforced by get_sb_single()), so only a reference counter of
 * the root directory and the associated superblock is
 * incremented. The last thread that releases the last reference to
 * the super block and eventually to the root directory causes the
 * whole filesystem to be released. See tcmi_ctlfs_kill_super() for
 * details on this.
 *
 * If the filesystem is already active (the vfs_mnt is valid), the
 * mount reference count is adjusted.
 *
 * It is necessary to protect the vfs_mnt variable as it can be
 * manipulated by other threads that might issue tcmi_ctlfs_put_root()
 * and release the vfs mount from under us.
 *
 * @return pointer to the root entry (reference counter adjusted by
 * tcmi_ctlfs_entry_get()) or NULL
 */
struct tcmi_ctlfs_entry* tcmi_ctlfs_get_root(void)
{
	down(&self.vfs_mnt_sem);
	/* when the VFS mount is currently inactive we have to create
	 * a new one */
	if (!self.vfs_mnt) {
		mdbg(INFO3, "Mounting");
		self.vfs_mnt = kern_mount(&self.fs_type);
		if (IS_ERR(self.vfs_mnt)) {
			minfo(ERR1, "Could not mount!");
			self.vfs_mnt = NULL;
			/* if the mount failed, the root directory
			 * instance doesn't exist too, so we don't
			 * need to explicitely delete it*/
			self.root_dir = NULL;
		}
	} 
	/* VFS mount still active, just increment its ref. counter */
	else
		mntget(self.vfs_mnt);
	up(&self.vfs_mnt_sem);

	mdbg(INFO3, "sb c_count=%d, s_active=%d", self.sb->s_count, 
	     atomic_read(&self.sb->s_active));
	mdbg(INFO3, "mount mnt_count=%d", atomic_read(&self.vfs_mnt->mnt_count));
	return tcmi_ctlfs_entry_get(self.root_dir);
}
static int fimc_is_ixc_video_close(struct file *file)
{
	int ret = 0;
	int refcount;
	struct fimc_is_video_ctx *vctx = file->private_data;
	struct fimc_is_video *video;
	struct fimc_is_device_ischain *device;

	BUG_ON(!file);
	BUG_ON(!vctx);
	BUG_ON(!GET_VIDEO(vctx));
	BUG_ON(!GET_DEVICE(vctx));

	video = GET_VIDEO(vctx);
	device = GET_DEVICE(vctx);

	ret = fimc_is_ischain_subdev_close(device, vctx);
	if (ret)
		merr("fimc_is_ischain_subdev_close is fail(%d)", device, ret);

	ret = fimc_is_video_close(vctx);
	if (ret)
		merr("fimc_is_video_close is fail(%d)", device, ret);

	refcount = close_vctx(file, video, vctx);
	if (refcount < 0)
		merr("close_vctx is fail(%d)", device, refcount);

	minfo("[I%dC:V] %s(%d,%d):%d\n", device, GET_IXC_ID(video), __func__, atomic_read(&device->open_cnt), refcount, ret);

	return ret;
}
static int fimc_is_ixc_video_open(struct file *file)
{
	int ret = 0;
	struct fimc_is_video *video;
	struct fimc_is_video_ctx *vctx;
	struct fimc_is_device_ischain *device;
	struct fimc_is_resourcemgr *resourcemgr;

	vctx = NULL;
	device = NULL;
	video = video_drvdata(file);
	resourcemgr = video->resourcemgr;
	if (!resourcemgr) {
		err("resourcemgr is NULL");
		ret = -EINVAL;
		goto p_err;
	}

	ret = fimc_is_resource_open(resourcemgr, RESOURCE_TYPE_ISCHAIN, (void **)&device);
	if (ret) {
		err("fimc_is_resource_open is fail(%d)", ret);
		goto p_err;
	}

	if (!device) {
		err("device is NULL");
		ret = -EINVAL;
		goto p_err;
	}

	minfo("[I%dC:V] %s\n", device, GET_IXC_ID(video), __func__);

	ret = open_vctx(file, video, &vctx, device->instance, FRAMEMGR_ID_IXC);
	if (ret) {
		merr("open_vctx is fail(%d)", device, ret);
		goto p_err;
	}

	ret = fimc_is_video_open(vctx,
		device,
		VIDEO_IXC_READY_BUFFERS,
		video,
		&fimc_is_ixc_qops,
		&fimc_is_ischain_subdev_ops);
	if (ret) {
		merr("fimc_is_video_open is fail(%d)", device, ret);
		close_vctx(file, video, vctx);
		goto p_err;
	}

	ret = fimc_is_ischain_subdev_open(device, vctx);
	if (ret) {
		merr("fimc_is_ischain_subdev_open is fail(%d)", device, ret);
		close_vctx(file, video, vctx);
		goto p_err;
	}

p_err:
	return ret;
}
Exemplo n.º 10
0
/** 
 * \<\<public\>\> Instance constructor.
 * - allocates a new instance.
 * - delegates its initialization to the super class.
 *
 * @param local_pid - local PID on PEN
 * @param migman - The migration manager that maintains this task
 * @param *sock - socket used for communication with shadow task on CCN
 * @param *d_migproc - directory where ctlfs entries of migrated
 * processes reside
 * @param *d_migman - TCMI ctlfs directory of the migration manager
 * responsible for this task
 * @return 0 upon success
 */
struct tcmi_task* tcmi_guesttask_new(pid_t local_pid, struct tcmi_migman* migman,
				    struct kkc_sock *sock, 
				    struct tcmi_ctlfs_entry *d_migproc, 
				    struct tcmi_ctlfs_entry *d_migman)
{
	struct tcmi_guesttask *task;
	minfo(INFO2, "Creating new TCMI guest task");
	if (!(task = TCMI_GUESTTASK(kmalloc(sizeof(struct tcmi_guesttask), 
						   GFP_ATOMIC)))) {
		mdbg(ERR3, "Can't allocate memory for TCMI ppm guest task");
		goto exit0;
	}
	if (tcmi_task_init(TCMI_TASK(task), local_pid, migman, sock, 
			   d_migproc, d_migman, &guesttask_ops) < 0) {
		mdbg(ERR3, "TCMI ppm guest task initialization failed!");
		goto exit1;
	}

	return TCMI_TASK(task);

	/* error handling */
 exit1:
	kfree(task);
 exit0:
	return NULL;
}
Exemplo n.º 11
0
static int fimc_is_ssx_video_close(struct file *file)
{
	int ret = 0;
	int refcount;
	struct fimc_is_video_ctx *vctx = file->private_data;
	struct fimc_is_video *video;
	struct fimc_is_device_sensor *device;

	BUG_ON(!vctx);
	BUG_ON(!GET_VIDEO(vctx));
	BUG_ON(!GET_DEVICE(vctx));

	video = GET_VIDEO(vctx);
	device = GET_DEVICE(vctx);

	ret = fimc_is_sensor_close(device);
	if (ret)
		merr("fimc_is_sensor_close is fail(%d)", device, ret);

	ret = fimc_is_video_close(vctx);
	if (ret)
		merr("fimc_is_video_close is fail(%d)", device, ret);

	refcount = close_vctx(file, video, vctx);
	if (refcount < 0)
		merr("close_vctx is fail(%d)", device, refcount);

	minfo("[SS%d:V] %s(%d):%d\n", device, GET_SSX_ID(video), __func__, refcount, ret);

	return ret;
}
Exemplo n.º 12
0
/** 
 *  \<\<private\>\> A method for inode allocation.  Currently the uid
 * and gid is assigned based on the current's fsuid and fsgid. Block
 * size is not relevant, set to page size.  If the user doesn't
 * specify any inode or file operations, the default(empty operations,
 * but not NULL) assigned by the VFS will be kept.
 *
 * If the user specified a parent directory inode, it's access rights
 * are investigated and inherited by the new inode as follows:
 * - if the parent has the SGID bit set, parent's gid is assigned to
 * the new inode.
 * - a parent SGID bit is set on the new inode, if the new inode is a 
 * directory
 * 
 *
 * @param *dir - inode of the parent directory for the new inode
 * @param *sb - super block of the filesystem where the inode is
 * to be allocated
 * @param *mode - file type and access rights for the inode
 * @param *i_ops - inode operations
 * @param *f_ops - file operations (also stored in the new inode)
 * @return a pointer to the new inode or NULL
 */
static struct inode* tcmi_ctlfs_get_inode(struct inode *dir, 
					  struct super_block *sb, 
					  mode_t mode,
					  const struct inode_operations *i_ops,
					  const struct file_operations *f_ops)
{
	struct inode *inode = new_inode(sb);

	if (inode) {
		inode->i_mode = mode;
		inode->i_uid = current_fsuid();
		inode->i_gid = current_fsgid();
		inode->i_blocks = 0;
		inode->i_op  = (i_ops ? i_ops : inode->i_op);
		inode->i_fop = (f_ops ? f_ops : inode->i_fop);
		inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
		mdbg(INFO4, "New inode allocated, inode number = %ld", inode->i_ino);
		/* check parent inode's(if any) access rights */
		if (dir && (dir->i_mode & S_ISGID)) {
			inode->i_gid = dir->i_gid;
			if (S_ISDIR(mode))
				inode->i_mode |= S_ISGID;
		}

	}
	else
		minfo(ERR3, "Failed to allocate a new inode");

	return inode;
}
Exemplo n.º 13
0
/**
 *  \<\<private\>\> A method for inode allocation.  Currently the uid
 * and gid is assigned based on the current's fsuid and fsgid. Block
 * size is not relevant, set to page size.  If the user doesn't
 * specify any inode or file operations, the default(empty operations,
 * but not NULL) assigned by the VFS will be kept.
 *
 * If the user specified a parent directory inode, it's access rights
 * are investigated and inherited by the new inode as follows:
 * - if the parent has the SGID bit set, parent's gid is assigned to
 * the new inode.
 * - a parent SGID bit is set on the new inode, if the new inode is a
 * directory
 *
 *
 * @param *dir - inode of the parent directory for the new inode
 * @param *sb - super block of the filesystem where the inode is
 * to be allocated
 * @param *mode - file type and access rights for the inode
 * @param *i_ops - inode operations
 * @param *f_ops - file operations (also stored in the new inode)
 * @return a pointer to the new inode or NULL
 */
static struct inode* tcmi_ctlfs_get_inode(struct inode *dir,
        struct super_block *sb,
        mode_t mode,
        const struct inode_operations *i_ops,
        const struct file_operations *f_ops)
{
    struct inode *inode = new_inode(sb);

    if (inode) {
        inode->i_mode = mode;
        inode->i_uid = current_fsuid();
        inode->i_gid = current_fsgid();
        inode->i_blocks = 0;
        inode->i_op  = (i_ops ? i_ops : inode->i_op);
        inode->i_fop = (f_ops ? f_ops : inode->i_fop);
        inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
        inode->i_ino = get_next_ino();    //Added number inode i_no in new kernel it must be assigned from return value function get_next_ino() which returns next number inode | by Jiri Rakosnik
        mdbg(INFO4, "New inode allocated, inode number = %ld", inode->i_ino);
        /* check parent inode's(if any) access rights */
        if (dir && (dir->i_mode & S_ISGID)) {
            inode->i_gid = dir->i_gid;
            if (S_ISDIR(mode))
                inode->i_mode |= S_ISGID;
        }

    }
    else
        minfo(ERR3, "Failed to allocate a new inode");

    return inode;
}
Exemplo n.º 14
0
/**
 * \<\<public\>\> TCMI CCN manager constructor.
 * The initialization is accomplished exactly in this order:
 * - create new instance
 * - allocate new slot vector for shadow processes.
 * - delegates all remaining intialization work to the generic manager.
 * - authenticate the connecting PEN
 * 
 * @param *parent - pointer to struct of parent for example - decrement count of connected nodes*
 * @param *sock - socket where the new PEN is registering
 * @param ccn_id - CCN identifier
 * @param *root - directory where the migration manager should create its
 * files and directories
 * @param *migproc - directory where the migrated process will have their info
 * @param namefmt - nameformat string for the main manager directory name (printf style)
 * @param ... - variable arguments
 * @return new TCMI CCN manager instance or NULL
 */
struct tcmi_migman* tcmi_ccnmigman_new(struct tcmi_man *parent, struct kkc_sock *sock, u_int32_t ccn_id, struct tcmi_slot* manager_slot,
					  struct tcmi_ctlfs_entry *root,
				       struct tcmi_ctlfs_entry *migproc,
					  const char namefmt[], ...)
{
	struct tcmi_ccnmigman *migman;
	va_list args;

	minfo(INFO2, "Creating new TCMI CCN migration manager");
	if (!(migman = TCMI_CCNMIGMAN(kmalloc(sizeof(struct tcmi_ccnmigman), 
					      GFP_KERNEL)))) {
		mdbg(ERR3, "Can't allocate memory for CCM migration manager");
		goto exit0;
	}
	init_waitqueue_head(&migman->wq);
	va_start(args, namefmt);
	if (tcmi_migman_init(parent ,TCMI_MIGMAN(migman), sock, ccn_id, 0, UNKNOWN, manager_slot, root, migproc,
			     &ccnmigman_ops, namefmt, args) < 0) {
		mdbg(ERR3, "TCMI CCN migman initialization failed!");
		va_end(args);
		goto exit1;
	}
	va_end(args);
	
	return TCMI_MIGMAN(migman);

	/* error handling */
 exit1:
	kfree(migman);
 exit0:
	return NULL;
}
static int fimc_is_comp_video_close(struct file *file)
{
	int ret = 0;
	int refcount;
	struct fimc_is_video_ctx *vctx = file->private_data;
	struct fimc_is_video *video = NULL;
	struct fimc_is_device_companion *device = NULL;

	BUG_ON(!vctx);

	video = video_drvdata(file);
	device = container_of(video, struct fimc_is_device_companion, video);

	ret = fimc_is_companion_close(device);
	if (ret)
		err("fimc_is_companion_close is fail(%d)", ret);

	vctx->device = NULL;

	refcount = close_vctx(file, video, vctx);
	if (refcount < 0)
		merr("close_vctx is fail(%d)", device, refcount);

	minfo("[COM:V] %s():%d\n", device, __func__, ret);

	return ret;
}
Exemplo n.º 16
0
/** 
 * \<\<public\>\> Called from method queue - Exits a task.  This
 * method is primarily intended terminate the main method processing
 * loop of the task. The task is then removed from its migration
 * manager and destroyed. Task specific method has the chance to
 * communicate this to its counter part. E.g. a guest task sends an
 * exit code to the associated shadow process on the CCN.
 *
 * The method wrapper might contain an exit code. If so, it is communicated
 * to the specific task method. The default exit code is 0.
 *
 * @param *self - pointer to this task instance
 * @param *wr - method wrapper that stores the requested exit code.
 * @return result of the task specific exit method or 
 * TCMI_TASK_REMOVE_AND_LET_ME_GO
 */
int tcmi_task_exit(void *self, struct tcmi_method_wrapper *wr)
{
	int res = TCMI_TASK_REMOVE_AND_LET_ME_GO;
	struct tcmi_task *self_tsk = TCMI_TASK(self);
	long *pcode, code;
	minfo(INFO3, "Doing exit");
	/* extract the exit code if any. */
	pcode = (long*)tcmi_method_wrapper_data(wr);
	code = (pcode ? *pcode : 0);

	minfo(INFO3, "Executing custom exit method");
	if (self_tsk->ops->exit)
		res = self_tsk->ops->exit(self_tsk, code);
	minfo(INFO3, "Executed custom exit method");

	return res;
}
Exemplo n.º 17
0
/**
 * Module initialization
 *
 * @return -
 */
static int __init kkc_test1_init(void)
{
    int err = 0;

    minfo(INFO1, "Starting KKC test");
    struct kkc_sock *new_sock = NULL;

    if (kkc_connect(&sock, "udp:192.168.0.3:5678"))
        minfo(ERR1, "Failed connecting to UDP, as expected, sock=%p", sock);

    if (kkc_connect(&sock, "tcp:192.168.0.3:5678"))
        minfo(ERR1, "Failed connecting to TCP, shouldn't fail..sock = %p", sock);
    else
        kkc_sock_put(sock);

    if (kkc_listen(&sock, "tcp:192.168.0.3:0")) {
        minfo(ERR1, "Failed listening on TCP, shouldn't fail.. sock=%p", sock);
        goto exit0;
    }
    minfo(INFO1, "Socket names-local: '%s', remote: '%s'",
          kkc_sock_getsockname2(sock), kkc_sock_getpeername2(sock));

    /* Accept the first incoming connection */
    if ((err = kkc_sock_accept(sock, &new_sock, KKC_SOCK_BLOCK)) < 0) {
        minfo(ERR1, "Accept terminated by with error code:%d",err);
        goto exit0;
    }
    minfo(INFO1, "Accepted incoming connection, terminating listening on: '%s'",
          kkc_sock_getsockname2(new_sock));
    /* destroy the listening socket*/
    kkc_sock_put(new_sock);
exit0:
    return 0;
}
Exemplo n.º 18
0
/** 
 * \<\<public\>\> Unregisters all syscalls hooks.
 */
void tcmi_syscall_hooks_other_exit(void)
{
	minfo(INFO1, "Unregistering TCMI other syscalls hooks"
			"(wait)");
	tcmi_hooks_unregister_sys_wait4();
	tcmi_hooks_unregister_pre_fork();
	tcmi_hooks_unregister_in_fork();
	tcmi_hooks_unregister_post_fork();
}
Exemplo n.º 19
0
/**
 *  \<\<private\>\> This class method is a custom implementation of a
 * VFS release_dentry operation.  The release_dentry is called by VFS
 * when releasing the dentry associated with a particular
 * tcmi_ctlfs_entry object. This happens when the dentry's reference
 * counter reaches 0.
 *
 * Unlike previous VFS method, we are allowed to sleep as the dcache
 * lock and dentry lock are not held anymore (see fs/dcache.c)
 *
 * @param *dentry - pointer to the dentry that is to be deleted
 * @return - always 1 since we don't want the VFS to put the dentry
 * into the dentry_unused. This way the dentry will be unhashed and
 * removed right away
 */
static void tcmi_ctlfs_dentry_release(struct dentry *dentry)
{
    /* get the instance first */
    struct tcmi_ctlfs_entry *self = TCMI_CTLFS_DENTRY_TO_ENTRY(dentry);
    if (self)
        tcmi_ctlfs_entry_release(self);
    else
        minfo(ERR2, "VFS issued dentry_release on a dentry without tcmi_ctlfs_instance!!");
}
Exemplo n.º 20
0
/** 
 * \<\<public\>\> Unregisters all syscalls hooks.
 */
void tcmi_syscall_hooks_exit(void)
{
	minfo(INFO1, "Unregistering TCMI syscalls hooks");
	tcmi_syscall_hooks_signal_exit();
	tcmi_syscall_hooks_pidman_exit();
	tcmi_syscall_hooks_userident_exit();
	tcmi_syscall_hooks_groupident_exit();
	tcmi_syscall_hooks_other_exit();
}
Exemplo n.º 21
0
/** 
 * \<\<public\>\> Registers all syscalls hooks with the kernel.
 *
 * @return 0 upon success
 */
int tcmi_syscall_hooks_init(void)
{
	minfo(INFO1, "Registering TCMI syscalls hooks");
	tcmi_syscall_hooks_signal_init();
	tcmi_syscall_hooks_pidman_init();
	tcmi_syscall_hooks_userident_init();
	tcmi_syscall_hooks_groupident_init();
	tcmi_syscall_hooks_other_init();
	return 0;
}
Exemplo n.º 22
0
/**
 * Module cleanup
 */
static void __exit tcmi_listening_test_exit(void)
{
	minfo(INFO1,"------------------- REMOVAL TESTING ------------------");
	struct tcmi_slot *sl1, *sl2;
	/* we will lock the entire slot vector and for the actual
	 * removal we use the __tcmi_slot_remove version that assumes
	 * the lock is already held There are removals, so we have to
	 * use the safe version for traversing */
	tcmi_slotvec_lock(vec);
	tcmi_slotvec_for_each_used_slot_safe(sl1, sl2, vec) {
		/* slot nodes needed for safe traversal */
		tcmi_slot_node_t *nd, *nd2; 
		struct tcmi_listening *listening;
		minfo(INFO1,"Searching slot %d", tcmi_slot_index(sl1));
		tcmi_slot_for_each_entry_safe(listening, nd, nd2, sl1, node) {
			minfo(INFO1,"Removing listening..");
			/* instance release, locks on the slot are held already */
			tcmi_listening_put(listening);
		}
Exemplo n.º 23
0
/** This handler is invoked when the sig_unused hook finds a non-NULL entry
 * in the clondike record in the task_struct */
void guest_mig_mode_handler(void)
{
	struct tcmi_task *tmp, *task;
	int res;
	long exit_code;

	minfo(INFO1, "Migration mode handler for task '%s' executing", 
	      current->comm);


	if (!(task = tcmi_taskhelper_sanity_check())) {
		minfo(ERR3, "Stub - invalid entry to migration mode - kernel task %p, PID=%d",
		      current, current->pid);
		goto exit0;
	}

	/* keep moving the task between migration managers */
	while ((res = tcmi_task_process_methods(task)) ==
	       TCMI_TASK_MOVE_ME);
	/* check the result of the last method processed */
	switch (res) {
	case TCMI_TASK_KEEP_PUMPING:
		minfo(INFO1, "KEEP PUMPING - but no methods left %d", res);
		break;
	case TCMI_TASK_LET_ME_GO:
		minfo(INFO1, "LET ME GO - request %d", res);
		break;
		/* no need for special handling a fall through causes
		 * do_exit which sends a message to the shadow */
	case TCMI_TASK_EXECVE_FAILED_KILL_ME:
		minfo(INFO1, "EXECVE_FAILED KILL ME - request %d", res);
		break;
	case TCMI_TASK_KILL_ME:
		minfo(INFO1, "KILL ME - request %d", res);
		tmp = tcmi_taskhelper_detach();
		/* get the exit code prior terminating. */
		exit_code = tcmi_task_exit_code(tmp);
		tcmi_task_put(tmp);
		complete_and_exit(NULL, exit_code);
		break;
	case TCMI_TASK_REMOVE_AND_LET_ME_GO:
		minfo(INFO1, "REMOVE AND LET ME GO - request %d", res);
		tcmi_task_put(tcmi_taskhelper_detach());
		break;
	default:
		minfo(ERR1, "Unexpected result %d.", res);
		break;
	}
	/* error handling */
 exit0:
	return;
}
Exemplo n.º 24
0
/** 
 * \<\<public\>\> Unregisters all PID manipulation syscalls hooks.
 */
void tcmi_syscall_hooks_pidman_exit(void)
{
	minfo(INFO3, "Unregistering TCMI PID manipulation syscalls hooks\n");
	tcmi_hooks_unregister_sys_getppid();
	tcmi_hooks_unregister_sys_getpid();
	tcmi_hooks_unregister_sys_getpgid();
	tcmi_hooks_unregister_sys_setpgid();
	tcmi_hooks_unregister_sys_getsid();
	tcmi_hooks_unregister_sys_setsid();
	tcmi_hooks_unregister_sys_getpgrp();
}
Exemplo n.º 25
0
static int fimc_is_ssx_video_open(struct file *file)
{
	int ret = 0;
	struct fimc_is_video *video;
	struct fimc_is_video_ctx *vctx;
	struct fimc_is_device_sensor *device;
	struct fimc_is_resourcemgr *resourcemgr;

	vctx = NULL;
	video = video_drvdata(file);
	device = container_of(video, struct fimc_is_device_sensor, video);
	resourcemgr = video->resourcemgr;
	if (!resourcemgr) {
		err("resourcemgr is NULL");
		ret = -EINVAL;
		goto p_err;
	}

	ret = fimc_is_resource_open(resourcemgr, video->id - FIMC_IS_VIDEO_SS0_NUM, NULL);
	if (ret) {
		err("fimc_is_resource_open is fail(%d)", ret);
		goto p_err;
	}

	minfo("[SS%d:V] %s\n", device, video->id, __func__);

	ret = open_vctx(file, video, &vctx, device->instance, FRAMEMGR_ID_SSX);
	if (ret) {
		merr("open_vctx is fail(%d)", device, ret);
		goto p_err;
	}

	ret = fimc_is_video_open(vctx,
		device,
		VIDEO_SSX_READY_BUFFERS,
		video,
		&fimc_is_ssx_qops,
		&fimc_is_sensor_ops);
	if (ret) {
		merr("fimc_is_video_open is fail(%d)", device, ret);
		close_vctx(file, video, vctx);
		goto p_err;
	}

	ret = fimc_is_sensor_open(device, vctx);
	if (ret) {
		merr("fimc_is_ssx_open is fail(%d)", device, ret);
		close_vctx(file, video, vctx);
		goto p_err;
	}

p_err:
	return ret;
}
Exemplo n.º 26
0
/** 
 * \<\<public\>\> Registers all syscalls hooks with the kernel.
 *
 * @return 0 upon success
 */
int tcmi_syscall_hooks_other_init(void)
{
	minfo(INFO1, "Registering TCMI other syscalls hooks\n"
			"(wait)");
	tcmi_hooks_register_sys_wait4(tcmi_syscall_hooks_sys_wait4);
	tcmi_hooks_register_pre_fork(tcmi_syscall_hooks_pre_fork);
	tcmi_hooks_register_in_fork(tcmi_syscall_hooks_in_fork);
	tcmi_hooks_register_post_fork(tcmi_syscall_hooks_post_fork);
	
	return 0;
}
Exemplo n.º 27
0
int migrated_home(pid_t pid) {
	struct migrated_home_params params;
	int ret;

	params.pid = pid;

	ret = msg_transaction_do(DIRECTOR_MIGRATED_HOME, &migrated_home_msg_ops, &params, 1);

	minfo(INFO3, "Migrated home. Pid:  %u -> Res: %d", pid, ret);

	return ret;
};
Exemplo n.º 28
0
/**
 * Module initialization
 *
 * @return - status of the register_filesystem() call
 */
static int __init tcmi_ctlfs_init(void)
{
	int error;
	minfo(INFO3, "Registering TCMI control filesystem");
	error = init_inodecache();
	if (error)
		return error;

	error = register_filesystem(&self.fs_type);

	return error;
}
/** 
 * \<\<public\>\> Unregisters all user identifikation syscalls hooks.
 */
void tcmi_syscall_hooks_groupident_exit(void)
{
	minfo(INFO3, "Unregistering TCMI group identification syscalls hooks");
	tcmi_hooks_unregister_sys_getegid();
	tcmi_hooks_unregister_sys_getgid();
	tcmi_hooks_unregister_sys_setgid();
	tcmi_hooks_unregister_sys_setregid();
	tcmi_hooks_unregister_sys_setresgid();
	tcmi_hooks_unregister_sys_getresgid();
	tcmi_hooks_unregister_sys_getgroups();
	tcmi_hooks_unregister_sys_setgroups();
}
Exemplo n.º 30
0
static int ccfs_open(struct inode *inode, struct file *file)
{
	struct file *lower_file = NULL;	
	struct ccfs_file* file_info = NULL;
	int rc = 0;
	struct ccfs_super* sb_info = ccfs_superblock_to_private(inode->i_sb);

	file_info = kmem_cache_zalloc(ccfs_file_cache, GFP_KERNEL);
	if ( !file_info ) {
		rc = -ENOMEM;
		goto out;
	}
	
	ccfs_set_file_private(file, file_info);

	if ( !ccfs_inode_to_private(inode)->cacheable ) {
		// Haven't found a reason why would we reopen file here, we just wait let the file close and invalidate when nobody is using it. It is not 100% correct thing in cases of races
		// but since this is just a toy FS for experimental measurements, we can leave it as it is (unless we want to measure something with races in FS;)
	  
		// TODO: This is a hack to reopen "root" dentry, it is not required for other entries. Moreover, we can now reset cacheable flag, but do we need to?
		// TODO: The comment above is really cryptic and not sure what I was trying to say :(... Generally, the files are refreshed when they are non-cacheable and
		// last reference to them is dropped which seems like a safe behaviour.. my suspition is, the comment was saying it does not happen for root node, which is always
		// held, but not sure.. for now disable due to caused races and if I find what is the real reason for this call I'll update this code/comment
		// ccfs_reopen_persistent_file(file->f_path.dentry, inode);
		
//		if ( !invalidate_inode_pages2(inode->i_mapping) ) {
//		    minfo(ERR3, "Cache invalidation has failed");
//		}
	}	

	lower_file = ccfs_inode_to_private(inode)->lower_file;
	mdbg(INFO3, "Opening inode %p (file %p) associated with lower file: %p (dname: [%s]) - cacheable: %d", inode, file, lower_file, file->f_dentry->d_name.name, ccfs_inode_to_private(inode)->cacheable);
	if ( !lower_file ) {
		minfo(ERR3, "Assertion failed! Lower file does not exist!");
		kmem_cache_free(ccfs_file_cache, file_info);
		rc = -ENOENT;
		goto out;		
	}

	ccfs_set_nested_file(file, lower_file);

	if ( sb_info->prefetch && S_ISREG(inode->i_mode) ) { // TODO: Schedule this only on first open of file?
		mdbg(INFO3,"Scheduling prefetch for inode %p", inode);
		// TODO: Uncommented as there seems to be some problem with prefetcher.. on freeing pages we usually got 
		// General protection fault.. it is probably caused by allocation of pages in context of a different proces?
		
		//atomic_inc(&file->f_count); // Get reference that'll be freed by prefetcher after the prefetch is done
		//submit_for_prefetch(file);
	}
out:
	return rc;	
}