Exemple #1
0
static int ipc_thread_exit (IDTYPE vmid, IDTYPE tid, unsigned int exitcode)
{
    assert(vmid != cur_process.vmid);

    struct shim_thread * thread = __lookup_thread(tid);

    if (thread) {
        int ret = 0;
        //assert(thread->vmid == vmid && !thread->in_vm);
        thread->exit_code = -exitcode;
        ret = thread_exit(thread, false);
        put_thread(thread);
        return ret;
    }

    struct shim_simple_thread * sthread = __lookup_simple_thread(tid);

    if (!sthread) {
        sthread = get_new_simple_thread();
        sthread->vmid = vmid;
        sthread->tid = tid;
        add_simple_thread(sthread);
    }

    sthread->is_alive = 0;
    sthread->exit_code = -exitcode;
    DkEventSet(sthread->exit_event);
    put_simple_thread(sthread);
    return 0;
}
Exemple #2
0
int try_process_exit (int error_code, int term_signal)
{
    struct shim_thread * cur_thread = get_cur_thread();

    cur_thread->exit_code = -error_code;
    cur_process.exit_code = error_code;
    cur_thread->term_signal = term_signal;

    if (cur_thread->in_vm)
        thread_exit(cur_thread, true);

    if (check_last_thread(cur_thread))
        return 0;

    struct shim_thread * async_thread = terminate_async_helper();
    if (async_thread)
        /* TODO: wait for the thread to exit in host.
         * This is tracked by the following issue.
         * https://github.com/oscarlab/graphene/issues/440
         */
        put_thread(async_thread); /* free resources of the thread */

    struct shim_thread * ipc_thread;
    int ret = exit_with_ipc_helper(true, &ipc_thread);
    if (ipc_thread)
        /* TODO: wait for the thread to exit in host.
         * This is tracked by the following issue.
         * https://github.com/oscarlab/graphene/issues/440
         */
        put_thread(ipc_thread); /* free resources of the thread */
    if (!ret)
        shim_clean(ret);
    else
        DkThreadExit();

    return 0;
}
Exemple #3
0
pid_t shim_do_wait4 (pid_t pid, int * status, int option,
                     struct __kernel_rusage * ru)
{
    struct shim_thread * cur = get_cur_thread();
    struct shim_thread * thread = NULL;
    int ret = 0;

    INC_PROFILE_OCCURENCE(syscall_use_ipc);

    if (pid > 0) {
        if (!(thread = lookup_thread(pid)))
            return -ECHILD;

        if (!(option & WNOHANG)) {
block_pid:
            DkObjectsWaitAny(1, &thread->exit_event,
                             NO_TIMEOUT);
        }

        lock(thread->lock);

        if (thread->is_alive) {
            unlock(thread->lock);
            if (!(option & WNOHANG))
                goto block_pid;
            put_thread(thread);
            return 0;
        }

        if (!list_empty(&thread->siblings)) {
            struct shim_thread * parent = thread->parent;
            assert(parent);

            lock(parent->lock);
            list_del_init(&thread->siblings);
            unlock(parent->lock);

            put_thread(parent);
            put_thread(thread);
            thread->parent = NULL;
        }

        unlock(thread->lock);
        goto found;
    }

    lock(cur->lock);

    if (list_empty(&cur->children) &&
        list_empty(&cur->exited_children)) {
        unlock(cur->lock);
        return -ECHILD;
    }

    if (!(option & WNOHANG)) {
block:
        if (cur->child_exit_event)
            while (list_empty(&cur->exited_children)) {
                unlock(cur->lock);
                DkObjectsWaitAny(1, &cur->child_exit_event, NO_TIMEOUT);
                lock(cur->lock);
            }
    }

    if (pid == 0 || pid < -1) {
        if (pid == 0)
            pid = -cur->pgid;

        list_for_each_entry(thread, &cur->exited_children, siblings)
            if (thread->pgid == -pid)
                goto found_child;

        if (!(option & WNOHANG))
            goto block;
    } else {
        if (!list_empty(&cur->exited_children)) {
Exemple #4
0
static int find_thread_link (const char * name, struct shim_qstr * link,
                             struct shim_dentry ** dentptr,
                             struct shim_thread ** threadptr)
{
    const char * next, * nextnext;
    int next_len;
    int pid = parse_thread_name(name, &next, &next_len, &nextnext);
    if (pid < 0)
        return pid;

    struct shim_thread * thread = lookup_thread(pid);
    struct shim_dentry * dent = NULL;
    int ret = 0;

    if (!thread)
        return -ENOENT;

    if (!thread->in_vm) {
        ret = -ENOENT;
        goto out;
    }

    lock(&thread->lock);

    if (next_len == static_strlen("root") && !memcmp(next, "root", next_len)) {
        dent = thread->root;
        get_dentry(dent);
    }

    if (next_len == static_strlen("cwd") && !memcmp(next, "cwd", next_len)) {
        dent = thread->cwd;
        get_dentry(dent);
    }

    if (next_len == static_strlen("exe") && !memcmp(next, "exe", next_len)) {
        struct shim_handle * exec = thread->exec;
        if (!exec->dentry) {
            unlock(&thread->lock);
            ret = -EINVAL;
            goto out;
        }
        dent = exec->dentry;
        get_dentry(dent);
    }

    unlock(&thread->lock);

    if (nextnext) {
        struct shim_dentry * next_dent = NULL;

        ret = path_lookupat(dent, nextnext, 0, &next_dent, dent->fs);
        if (ret < 0)
            goto out;

        put_dentry(dent);
        dent = next_dent;
    }

    if (link) {
        int size;
        char * path = dentry_get_path(dent, true, &size);
        qstrsetstr(link, path, size);
    }

    if (dentptr) {
        get_dentry(dent);
        *dentptr = dent;
    }

    if (threadptr) {
        get_thread(thread);
        *threadptr = thread;
    }

    ret = 0;
out:
    if (dent)
        put_dentry(dent);
    if (thread)
        put_thread(thread);
    return ret;
}