Ejemplo n.º 1
0
/**
	Function Name : process_sched_add_module_write
	Function Type : Kernel Callback Method
	Description   : Method is invoked whenever the process_sched_add
					file is written. This callback method is triggered 
					when a write operation performed on the above 
					mentioned file which is registered to the file 
					operation object. 
					/proc/process_sched_add is a write only file.
*/
static ssize_t process_sched_add_module_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
{
	int ret;
	long int new_proc_id;	
	
	printk(KERN_INFO "Process Scheduler Add Module write.\n");
	printk(KERN_INFO "Registered Process ID: %s\n", buf);
	
	ret = kstrtol(buf,BASE_10,&new_proc_id);
	if(ret < 0) {
		/** Invalid argument in conversion error.*/
		return -EINVAL;
	}
	
	/**	Add process to the process queue.*/
	ret = add_process_to_queue(new_proc_id);
	/**Check if the add process to queue method was successful or not.*/
	if(ret != eExecSuccess) {
		printk(KERN_ALERT "Process Set ERROR:add_process_to_queue function failed from sched set write method");
		/** Add process to queue error.*/
		return -ENOMEM;
	}

	/** Successful execution of write call back.*/
	return count;
}
Ejemplo n.º 2
0
int32_t switch_process_queue(process_t *proc, QueueType to_q)
{
    process_t *proc_to_switch = pop_process_from_queue(proc);
    if (!proc_to_switch)
        return -1;

    if (curr_running_proc == proc_to_switch)
    {
        curr_running_proc =  NULL;
    }

    add_process_to_queue(proc_to_switch, to_q);
    return 0;
}
Ejemplo n.º 3
0
//Initializes a process with its binary its argument
process_t* create_process_new(void* binary, pid_t ppid, int new_pid, 
                              const char *proc_name,
                              char * const argv[],
                              size_t argv_count,
                              char * const envp[],
                              size_t envp_count)
{
    uint64_t old_cr3 = 0;
    int32_t    rc   = 0;

    process_t *proc = allocate_process(new_pid);
    if (!proc)
    {
        #ifdef LOG
            printf("Failed to allocate memory for process\n");
        #endif
        return NULL;
    }
    
    // First process will be foreground... Need to change this logic
    // May be this will work fine when we will be running just shell
    if (foreground_proc == NULL)
    {
        proc->flags |= FOREGROUND_PROCESS;
        foreground_proc = proc;
    }

    strncpy(proc->name, proc_name, sizeof(proc->name));

    proc->kernel_stack = kmalloc(USER_KERNEL_STACK_SIZE);
    if(proc->kernel_stack == NULL)
    {
        reclaim_process_resources(proc);
        kfree(proc);
        #if LOG
            printf("failed to allocate memory for user-kern stack\n");
        #endif
        
        return NULL;
    }

    rc = setup_pagetable_proc(proc);
    if (rc)
    {
        reclaim_process_resources(proc);
        kfree(proc);
        #ifdef LOG
            printf("setup_pagetable_proc failed\n");
        #endif
        return NULL;
    }
    
    if (binary != NULL)
    {
        //If the process is child of some parent
        //So we don't need any binary
        rc = init_vmas_proc(proc, binary, argv_count, envp_count);
    }

    if (rc)
    {
        reclaim_process_resources(proc);
        kfree(proc);
        #ifdef LOG
            printf("init_vmas_proc failed\n");
        #endif
        return NULL;
    }

    //Setup registers for the process
    setup_registers_proc(proc);

    // Allocate a page for stack
    // Why we are not going for demand paging?
    //  We need to push env variables' addresses on stack while we are in kernel 
    //  and it's not a good idea to have a page fault in kernel
    if (binary != NULL)
    {   //Don't allocate page for stack because it's a child.
        allocate_memory((uint64_t)proc->page_table_base,
                    USER_STACK_TOP - PGSIZE,
                    PGSIZE,
                    PTE_P | PTE_U | PTE_W);
    }
    // This function should be last in this sequence since it uses rsp 
    // which we set in setup_registers_proc
    if (binary != NULL)
    {

        if (argv_count > 0)
        {
            allocate_memory((uint64_t)proc->page_table_base,
                            USER_ARGV_START,
                            argv_count * sizeof(execve_argv[0]),
                            PTE_P | PTE_U | PTE_W);
            old_cr3 = getcr3();
            setcr3((uint64_t)proc->page_table_base);
            memcpy((void *)USER_ARGV_START,
                    argv,
                    argv_count * sizeof(execve_argv[0]));
            setcr3(old_cr3);
        }

        if (envp_count > 0)
        {
            allocate_memory((uint64_t)proc->page_table_base,
                            USER_ENV_VARIABLE_START,
                            envp_count * sizeof(execve_envp[0]),
                            PTE_P | PTE_U | PTE_W);
            old_cr3 = getcr3();
            setcr3((uint64_t)proc->page_table_base);
            memcpy((void *)USER_ENV_VARIABLE_START,
                    envp,
                    envp_count * sizeof(execve_envp[0]));
            setcr3(old_cr3);
        }

        setup_stack(proc, argv_count, envp_count);
    }

    add_process_to_queue(proc, PROCESS_RUNNABLE_QUEUE);
    proc->ppid = ppid;
    //printf("New process PID = %d\n", proc->pid);

    return proc;
}
Ejemplo n.º 4
0
int terminate_process(process_t *proc, int return_value)
{
    if (!proc)
        return -1;

    reparent_children(proc);
    
    //printf("Killing process [%d]:%s \n", proc->pid, proc->name);
    if (proc == foreground_proc)
    {
        // Make parent of current process as foreground
        process_t *parent_proc = get_proc_from_pid(proc->ppid);
        if (parent_proc)
        {
            /* No point in making init the foreground proc. Make root
             * shell the BOSS
             */
            if ( parent_proc->pid == 1 )
            {
                parent_proc = get_proc_from_pid(2);
            }
            parent_proc->flags |= FOREGROUND_PROCESS;
            proc->flags &= ~FOREGROUND_PROCESS;
            foreground_proc = parent_proc;
        }
        else
        {
            /* Set it to root shell */
            foreground_proc = get_proc_from_pid(2);
        }
    }

    // Just deallocate resources but keep the process structure
    // and move process to TERMINATED QUEUE
    proc = pop_process_from_queue(proc);

    if (curr_running_proc == proc)
    {
        curr_running_proc =  NULL;
    }

    reclaim_process_resources(proc);

    kfree(delete_prev_stack);
    delete_prev_stack = proc->kernel_stack;
    proc->kernel_stack = NULL;

    add_process_to_queue(proc, PROCESS_TERMINATED_QUEUE);

    proc->exit_status = (return_value & 0xff);
    // If I am being waited upon by my parent, wake them up
    if (proc->flags & PAPA_WAITING)
    {
        process_t *parent_proc = get_proc_from_pid(proc->ppid);
        if (!parent_proc)
        {
            #ifdef LOG
                printf("Failed to get parent process during termination\n");
            #endif
            return -1;
        }
        switch_process_queue(parent_proc, PROCESS_RUNNABLE_QUEUE);
    }

    return 0;
}