Beispiel #1
0
static void virNetServerHandleJob(void *jobOpaque, void *opaque)
{
    virNetServerPtr srv = opaque;
    virNetServerJobPtr job = jobOpaque;

    VIR_DEBUG("server=%p client=%p message=%p prog=%p",
              srv, job->client, job->msg, job->prog);

    if (virNetServerProcessMsg(srv, job->client, job->prog, job->msg) < 0)
        goto error;

    virNetServerLock(srv);
    virObjectUnref(job->prog);
    virNetServerUnlock(srv);

    virObjectUnref(job->client);
    VIR_FREE(job);
    return;

error:
    virObjectUnref(job->prog);
    virNetMessageFree(job->msg);
    virNetServerClientClose(job->client);
    virObjectUnref(job->client);
    VIR_FREE(job);
}
Beispiel #2
0
static void virNetServerHandleJob(void *jobOpaque, void *opaque)
{
    virNetServerPtr srv = opaque;
    virNetServerJobPtr job = jobOpaque;

    VIR_DEBUG("server=%p client=%p message=%p prog=%p",
              srv, job->client, job->msg, job->prog);

    if (!job->prog) {
        /* Only send back an error for type == CALL. Other
         * message types are not expecting replies, so we
         * must just log it & drop them
         */
        if (job->msg->header.type == VIR_NET_CALL ||
            job->msg->header.type == VIR_NET_CALL_WITH_FDS) {
            if (virNetServerProgramUnknownError(job->client,
                                                job->msg,
                                                &job->msg->header) < 0)
                goto error;
        } else {
            VIR_INFO("Dropping client mesage, unknown program %d version %d type %d proc %d",
                     job->msg->header.prog, job->msg->header.vers,
                     job->msg->header.type, job->msg->header.proc);
            /* Send a dummy reply to free up 'msg' & unblock client rx */
            virNetMessageClear(job->msg);
            job->msg->header.type = VIR_NET_REPLY;
            if (virNetServerClientSendMessage(job->client, job->msg) < 0)
                goto error;
        }
        goto cleanup;
    }

    if (virNetServerProgramDispatch(job->prog,
                                    srv,
                                    job->client,
                                    job->msg) < 0)
        goto error;

    virNetServerLock(srv);
    virNetServerProgramFree(job->prog);
    virNetServerUnlock(srv);

cleanup:
    virNetServerClientFree(job->client);
    VIR_FREE(job);
    return;

error:
    virNetServerProgramFree(job->prog);
    virNetMessageFree(job->msg);
    virNetServerClientClose(job->client);
    virNetServerClientFree(job->client);
    VIR_FREE(job);
}
Beispiel #3
0
static int virNetServerDispatchNewMessage(virNetServerClientPtr client,
                                          virNetMessagePtr msg,
                                          void *opaque)
{
    virNetServerPtr srv = opaque;
    virNetServerProgramPtr prog = NULL;
    unsigned int priority = 0;
    size_t i;
    int ret = -1;

    VIR_DEBUG("server=%p client=%p message=%p",
              srv, client, msg);

    virNetServerLock(srv);
    for (i = 0 ; i < srv->nprograms ; i++) {
        if (virNetServerProgramMatches(srv->programs[i], msg)) {
            prog = srv->programs[i];
            break;
        }
    }

    if (srv->workers) {
        virNetServerJobPtr job;

        if (VIR_ALLOC(job) < 0) {
            virReportOOMError();
            goto cleanup;
        }

        job->client = client;
        job->msg = msg;

        if (prog) {
            virObjectRef(prog);
            job->prog = prog;
            priority = virNetServerProgramGetPriority(prog, msg->header.proc);
        }

        ret = virThreadPoolSendJob(srv->workers, priority, job);

        if (ret < 0) {
            VIR_FREE(job);
            virObjectUnref(prog);
        }
    } else {
        ret = virNetServerProcessMsg(srv, client, prog, msg);
    }

cleanup:
    virNetServerUnlock(srv);

    return ret;
}
Beispiel #4
0
static int virNetServerDispatchNewClient(virNetServerServicePtr svc ATTRIBUTE_UNUSED,
                                         virNetServerClientPtr client,
                                         void *opaque)
{
    virNetServerPtr srv = opaque;

    virNetServerLock(srv);

    if (srv->nclients >= srv->nclients_max) {
        virNetError(VIR_ERR_RPC,
                    _("Too many active clients (%zu), dropping connection from %s"),
                    srv->nclients_max, virNetServerClientRemoteAddrString(client));
        goto error;
    }

    if (virNetServerClientInit(client) < 0)
        goto error;

    if (srv->clientInitHook &&
        srv->clientInitHook(srv, client) < 0)
        goto error;

    if (VIR_EXPAND_N(srv->clients, srv->nclients, 1) < 0) {
        virReportOOMError();
        goto error;
    }
    srv->clients[srv->nclients-1] = client;
    virNetServerClientRef(client);

    virNetServerClientSetDispatcher(client,
                                    virNetServerDispatchNewMessage,
                                    srv);

    virNetServerClientInitKeepAlive(client, srv->keepaliveInterval,
                                    srv->keepaliveCount);

    virNetServerUnlock(srv);
    return 0;

error:
    virNetServerUnlock(srv);
    return -1;
}