Пример #1
0
static serv_connection_t
serv_connect_internal(char *serverPath, bool paramBuffer)
{
    _svprintf("Connecting to server [%s]...\n", serverPath);
    serv_connection_t sc;
    memset(&sc, 0, sizeof(serv_connection_t));
    sc.error = EINVALID;

    /* Resolve server path to find the server's anon cap. */
    _svprintf("    Querying nameserv to find anon cap for [%s]....\n", serverPath);
    printf("    Querying nameserv to find anon cap for [%s]....\n", serverPath);
    sc.serverMountPoint = nsv_resolve(serverPath);
    if (!sc.serverMountPoint.success || ROS_ERRNO() != ESUCCESS) {
        _svprintf("    WARNING: Server not found.\n");
        printf("    WARNING: Server not found.\n");
        sc.error = ESERVERNOTFOUND;
        goto exit1;
    }

    _svprintf("    Result path prefix [%s] anon 0x%x dspace [%s]....\n",
        sc.serverMountPoint.nameservPathPrefix, sc.serverMountPoint.serverAnon,
        sc.serverMountPoint.dspaceName);
    printf("    Result path prefix [%s] anon 0x%x dspace [%s]....\n",
        sc.serverMountPoint.nameservPathPrefix, sc.serverMountPoint.serverAnon,
        sc.serverMountPoint.dspaceName);
    if (serv_special_connectless_server(sc.serverMountPoint.serverAnon)) {
        /* Connectionless server. */
        _svprintf("    Known connectionless server detected.\n");
        printf("    Known connectionless server detected.\n");
        sc.connectionLess = true;
        sc.serverSession = sc.serverMountPoint.serverAnon;
        sc.error = ESUCCESS;
        return sc;
    } else {
        /* Make connection request to server using the anon cap. */
        _svprintf("    Make connection request to server [%s] using the anon cap 0x%x...\n",
                serverPath, sc.serverMountPoint.serverAnon);
        printf("    Make connection request to server [%s] using the anon cap 0x%x...\n",
                serverPath, sc.serverMountPoint.serverAnon);
        sc.serverSession = serv_connect_direct(sc.serverMountPoint.serverAnon, REFOS_LIVENESS,
                                               &sc.error);
    }
    if (!sc.serverSession || sc.error != ESUCCESS) {
        _svprintf("    WARNING: Failed to anonymously connect to server.\n");
        printf("    WARNING: Failed to anonymously connect to server.\n");
        goto exit2;
    }

    /* Try pinging the server. */
    int error = serv_ping(sc.serverSession);
    if (error) {
        _svprintf("    WARNING: Failed to ping file server.\n");
        printf("    WARNING: Failed to ping file server.\n");
        sc.error = error;
        goto exit3;
    }

    /* Set up the parameter buffer between client (ie. us) and server. */
    if (paramBuffer) {
        sc.paramBuffer = data_open_map(REFOS_PROCSERV_EP, "anon", 0, 0,
                                       PROCESS_PARAM_DEFAULTSIZE, -1);
        if (sc.paramBuffer.err != ESUCCESS) {
            _svprintf("    WARNING: Failed to create param buffer dspace.\n");
            printf("    WARNING: Failed to create param buffer dspace.\n");
            sc.error = sc.paramBuffer.err;
            goto exit3;
        }
        assert(sc.paramBuffer.window && sc.paramBuffer.dataspace);
        assert(sc.paramBuffer.vaddr != NULL);

        /* Set this parameter buffer on server. */
        error = serv_set_param_buffer(sc.serverSession, sc.paramBuffer.dataspace,
                                      PROCESS_PARAM_DEFAULTSIZE);
        if (error) {
            _svprintf("    Failed to set remote server parameter buffer.");
            printf("    Failed to set remote server parameter buffer.");
            sc.error = error;
            goto exit4;
        }
    } else {
        sc.paramBuffer.err = -1;
    }

    _svprintf("Successfully connected to server [%s]!\n", serverPath);
    printf("Successfully connected to server [%s]!\n", serverPath);
    sc.error = ESUCCESS;
    return sc;

    /* Exit stack. */
exit4:
    assert(sc.paramBuffer.err == ESUCCESS);
    data_mapping_release(sc.paramBuffer);
exit3:
    assert(sc.serverSession);
    if (!sc.connectionLess) {
        serv_disconnect_direct(sc.serverSession);
        seL4_CNode_Delete(REFOS_CSPACE, sc.serverSession, REFOS_CDEPTH);
        csfree(sc.serverSession);
    }
exit2:
    nsv_mountpoint_release(&sc.serverMountPoint);
exit1:
    assert(sc.error != ESUCCESS);
    return sc;
}
Пример #2
0
int
srv_common_init(srv_common_t *s, srv_common_config_t config)
{
    assert(s);

    dprintf("Initialising %s common server state...\n", config.serverName);
    memset(s, 0, sizeof(srv_common_t));
    s->config = config;

    /* Create sync anon EP. */
    dprintf("    creating %s anon endpoint...\n", config.serverName);
    s->anonEP = proc_new_endpoint();
    if (!s->anonEP) {
        ROS_ERROR("srv_common_init could not create endpoint for %s.", config.serverName);
        return ENOMEM;
    }

    /* Create async EP. */
    dprintf("    creating %s async endpoint...\n", config.serverName);
    s->notifyAsyncEP = proc_new_async_endpoint();
    if (!s->notifyAsyncEP) {
        ROS_ERROR("srv_common_init could not create async endpoint.");
        return ENOMEM;
    }

    /* Mint badged async EP. */
    dprintf("    creating async death and/or fault notification badged EP...\n");
    s->notifyClientFaultDeathAsyncEP = srv_mint(config.faultDeathNotifyBadge, s->notifyAsyncEP);
    if (!s->notifyClientFaultDeathAsyncEP) {
        ROS_ERROR("srv_common_init could not create minted async endpoint.");
        return EINVALID;
    }

    /* Bind the notification AEP. */
    dprintf("    binding notification AEP...\n");
    int error = seL4_TCB_BindNotification(REFOS_THREAD_TCB, s->notifyAsyncEP);
    if (error != seL4_NoError) {
        ROS_ERROR("srv_common_init could not bind async endpoint.");
        return EINVALID;
    }

    /* Register ourselves under our mountpoint name. */
    if (config.mountPointPath != NULL) {
        dprintf("    registering under the mountpoint [%s]...\n", config.mountPointPath);
        error = nsv_register(config.nameServEP, config.mountPointPath, s->anonEP);
        if (error != ESUCCESS) {
            ROS_ERROR("srv_common_init could not register anon ep.");
            return error;
        }
    }

    /* Initialise client table. */
    if (config.maxClients > 0) {
        dprintf("    initialising client table for %s...\n", config.serverName);
        client_table_init(&s->clientTable, config.maxClients, config.clientBadgeBase,
                          config.clientMagic, s->anonEP);

        dprintf("    initialising client table default handlers for %s...\n", config.serverName);
        s->ctable_connect_direct_handler = srv_ctable_connect_direct_handler;
        s->ctable_set_param_buffer_handler = srv_ctable_set_param_buffer_handler;
        s->ctable_disconnect_direct_handler = srv_ctable_disconnect_direct_handler;
    }

    /* Set up our server --> process server notification buffer. */
    if (config.notificationBufferSize > 0) {

        /* Open and map the notification buffer on our side. */
        dprintf("    initialising notification buffer for %s...\n", config.serverName);
        s->notifyBuffer = data_open_map(REFOS_PROCSERV_EP, "anon", 0, 0,
                                        config.notificationBufferSize, -1);
        if (s->notifyBuffer.err != ESUCCESS) {
            ROS_ERROR("srv_common_init failed to open & map anon dspace for notifications.");
            return s->notifyBuffer.err;
        }

        /* Share and set the notification buffer on the procserv side. */
        assert(s->notifyBuffer.dataspace);
        error = proc_notification_buffer(s->notifyBuffer.dataspace);
        if (error != ESUCCESS) {
            ROS_ERROR("srv_common_init failed to set notification buffer.");
            return error;
        }

        s->notifyBufferStart = 0;
    }

    /* Set up our server --> process server parameter buffer. */
    if (config.paramBufferSize > 0) {

        dprintf("    initialising procserv param buffer for %s...\n", config.serverName);
        s->procServParamBuffer = data_open_map(REFOS_PROCSERV_EP, "anon", 0, 0,
                                               config.paramBufferSize, -1);
        if (s->procServParamBuffer.err != ESUCCESS) {
            ROS_ERROR("srv_common_init failed to open & map anon dspace for param buffer.");
            return s->procServParamBuffer.err;
        }
        error = proc_set_parambuffer(s->procServParamBuffer.dataspace, config.paramBufferSize);
        if (error != ESUCCESS) {
            ROS_ERROR("srv_common_init failed to set procserv param buffer.");
            return error;
        }
    }

    s->magic = SRV_MAGIC;
    return ESUCCESS;
}