Esempio n. 1
0
int
__pmRecvLabel(int fd, __pmContext *ctxp, int timeout,
	 	int *ident, int *type, pmLabelSet **sets, int *nsets)
{
    __pmPDU	*pb;
    int		oident = *ident;
    int		otype = *type;
    int		pinpdu;
    int		sts;

    sts = pinpdu = __pmGetPDU(fd, ANY_SIZE, timeout, &pb);
    if (sts == PDU_LABEL) {
	sts = __pmDecodeLabel(pb, ident, type, sets, nsets);
	if (sts >= 0) {
	    /* verify response is for a matching request */
	    if (oident != *ident || otype != *type)
		sts = PM_ERR_IPC;
	}
    }
    else if (sts == PDU_ERROR)
	__pmDecodeError(pb, &sts);
    else if (sts != PM_ERR_TIMEOUT)
	sts = PM_ERR_IPC;

    if (pinpdu > 0)
	__pmUnpinPDUBuf(pb);

    return sts;
}
Esempio n. 2
0
static int
ping_pmcd(int ctx)
{
    /*
     * We're going to leveraging an existing host context, just make sure
     * pmcd is still alive at the other end ... we don't have a "ping"
     * pdu, but sending a pmDesc request for PM_ID_NULL is pretty much
     * the same thing ... expect a PM_ERR_PMID error PDU back.
     * The code here is based on pmLookupDesc() with some short cuts
     * because we know it is a host context and we already hold the
     * __pmLock_libpcp lock
     */
    __pmContext	*ctxp = contexts[ctx];
    int		sts;

    PM_LOCK(ctxp->c_pmcd->pc_lock);
    if ((sts = __pmSendDescReq(ctxp->c_pmcd->pc_fd, ctx, PM_ID_NULL)) >= 0) {
	int	pinpdu;
	__pmPDU	*pb;
	pinpdu = __pmGetPDU(ctxp->c_pmcd->pc_fd, ANY_SIZE,
				    ctxp->c_pmcd->pc_tout_sec, &pb);
	if (pinpdu == PDU_ERROR)
	    __pmDecodeError(pb, &sts);
	if (pinpdu > 0)
	    __pmUnpinPDUBuf(pb);
    }
    PM_UNLOCK(ctxp->c_pmcd->pc_lock);

    if (sts != PM_ERR_PMID) {
	/* pmcd is not well on this context ... */
	return 0;
    }
    return 1;
}
Esempio n. 3
0
static int
__pmAuthServerNegotiation(int fd, int ssf, __pmHashCtl *attrs)
{
    int sts, saslsts;
    int pinned, length, count;
    char *payload, *offset;
    sasl_conn_t *sasl_conn;
    __pmPDU *pb;

    if (pmDebugOptions.auth)
	fprintf(stderr, "__pmAuthServerNegotiation(fd=%d, ssf=%d)\n",
		fd, ssf);

    if ((sasl_conn = (sasl_conn_t *)__pmGetUserAuthData(fd)) == NULL)
        return -EINVAL;

    /* setup all the security properties for this connection */
    if ((sts = __pmAuthServerSetProperties(sasl_conn, ssf)) < 0)
	return sts;

    saslsts = sasl_listmech(sasl_conn,
			    NULL, NULL, " ", NULL,
                            (const char **)&payload,
                            (unsigned int *)&length,
                            &count);
    if (saslsts != SASL_OK && saslsts != SASL_CONTINUE) {
	pmNotifyErr(LOG_ERR, "Generating client mechanism list: %s",
			sasl_errstring(saslsts, NULL, NULL));
	return __pmSecureSocketsError(saslsts);
    }
    if (pmDebugOptions.auth)
	fprintf(stderr, "__pmAuthServerNegotiation - sending mechanism list "
		"(%d items, %d bytes): \"%s\"\n", count, length, payload);

    if ((sts = __pmSendAuth(fd, FROM_ANON, 0, payload, length)) < 0)
	return sts;

    if (pmDebugOptions.auth)
	fprintf(stderr, "__pmAuthServerNegotiation - wait for mechanism\n");

    sts = pinned = __pmGetPDU(fd, ANY_SIZE, TIMEOUT_DEFAULT, &pb);
    if (sts == PDU_AUTH) {
        sts = __pmDecodeAuth(pb, &count, &payload, &length);
        if (sts >= 0) {
	    for (count = 0; count < length; count++) {
		if (payload[count] == '\0')
		    break;
	    }
	    if (count < length)	{  /* found an initial response */
		length = length - count - 1;
		offset = payload + count + 1;
	    } else {
		length = 0;
		offset = NULL;
	    }

	    saslsts = sasl_server_start(sasl_conn, payload,
				offset, length,
				(const char **)&payload,
				(unsigned int *)&length);
	    if (saslsts != SASL_OK && saslsts != SASL_CONTINUE) {
		sts = __pmSecureSocketsError(saslsts);
		if (pmDebugOptions.auth)
		    fprintf(stderr, "sasl_server_start failed: %d (%s)\n",
				    saslsts, pmErrStr(sts));
	    } else {
		if (pmDebugOptions.auth)
		    fprintf(stderr, "sasl_server_start success: sts=%s\n",
			    saslsts == SASL_CONTINUE ? "continue" : "ok");
	    }
	}
    }
    else if (sts == PDU_ERROR)
	__pmDecodeError(pb, &sts);
    else if (sts != PM_ERR_TIMEOUT)
	sts = PM_ERR_IPC;

    if (pinned > 0)
	__pmUnpinPDUBuf(pb);
    if (sts < 0)
	return sts;

    if (pmDebugOptions.auth)
	fprintf(stderr, "__pmAuthServerNegotiation method negotiated\n");

    while (saslsts == SASL_CONTINUE) {
	if (!payload) {
	    pmNotifyErr(LOG_ERR, "No SASL data to send");
	    sts = -EINVAL;
	    break;
	}
	if ((sts = __pmSendAuth(fd, FROM_ANON, 0, payload, length)) < 0)
	    break;

	if (pmDebugOptions.auth)
	    fprintf(stderr, "__pmAuthServerNegotiation awaiting response\n");

	sts = pinned = __pmGetPDU(fd, ANY_SIZE, TIMEOUT_DEFAULT, &pb);
	if (sts == PDU_AUTH) {
	    sts = __pmDecodeAuth(pb, &count, &payload, &length);
	    if (sts >= 0) {
		sts = saslsts = sasl_server_step(sasl_conn, payload, length,
                                                 (const char **)&payload,
                                                 (unsigned int *)&length);
		if (sts != SASL_OK && sts != SASL_CONTINUE) {
		    sts = __pmSecureSocketsError(sts);
		    break;
		}
		if (pmDebugOptions.auth) {
		    fprintf(stderr, "__pmAuthServerNegotiation"
				    " step recv (%d bytes)\n", length);
		}
	    }
	}
	else if (sts == PDU_ERROR)
	    __pmDecodeError(pb, &sts);
	else if (sts != PM_ERR_TIMEOUT)
	    sts = PM_ERR_IPC;

	if (pinned > 0)
	    __pmUnpinPDUBuf(pb);
	if (sts < 0)
	    break;
    }

    if (sts < 0) {
	if (pmDebugOptions.auth)
	    fprintf(stderr, "__pmAuthServerNegotiation loop failed: %d\n", sts);
	return sts;
    }

    return __pmAuthServerSetAttributes(sasl_conn, attrs);
}
Esempio n. 4
0
File: fetch.c Progetto: Aconex/pcp
int
pmFetch(int numpmid, pmID pmidlist[], pmResult **result)
{
    int		n;

    if (numpmid < 1) {
	n = PM_ERR_TOOSMALL;
	goto done;
    }

    if ((n = pmWhichContext()) >= 0) {
	__pmContext	*ctxp = __pmHandleToPtr(n);
	int		newcnt;
	pmID		*newlist = NULL;
	int		have_dm;

	if (ctxp == NULL) {
	    n = PM_ERR_NOCONTEXT;
	    goto done;
	}
	if (ctxp->c_type == PM_CONTEXT_LOCAL && PM_MULTIPLE_THREADS(PM_SCOPE_DSO_PMDA)) {
	    /* Local context requires single-threaded applications */
	    n = PM_ERR_THREAD;
	    PM_UNLOCK(ctxp->c_lock);
	    goto done;
	}

	/* for derived metrics, may need to rewrite the pmidlist */
	have_dm = newcnt = __pmPrepareFetch(ctxp, numpmid, pmidlist, &newlist);
	if (newcnt > numpmid) {
	    /* replace args passed into pmFetch */
	    numpmid = newcnt;
	    pmidlist = newlist;
	}

	if (ctxp->c_type == PM_CONTEXT_HOST) {
	    /*
	     * Thread-safe note
	     *
	     * Need to be careful here, because the PMCD changed protocol
	     * may mean several PDUs are returned, but __pmDecodeResult()
	     * may request more info from PMCD if pmDebug is set.
	     *
	     * So unlock ctxp->c_pmcd->pc_lock as soon as possible.
	     */
	    PM_LOCK(ctxp->c_pmcd->pc_lock);
	    if ((n = request_fetch(n, ctxp, numpmid, pmidlist)) >= 0) {
		int changed = 0;
		do {
		    __pmPDU	*pb;
		    int		pinpdu;

		    pinpdu = n = __pmGetPDU(ctxp->c_pmcd->pc_fd, ANY_SIZE,
					    ctxp->c_pmcd->pc_tout_sec, &pb);
		    if (n == PDU_RESULT) {
			PM_UNLOCK(ctxp->c_pmcd->pc_lock);
			n = __pmDecodeResult(pb, result);
		    }
		    else if (n == PDU_ERROR) {
			__pmDecodeError(pb, &n);
			if (n > 0)
			    /* PMCD state change protocol */
			    changed = n;
			else
			    PM_UNLOCK(ctxp->c_pmcd->pc_lock);
		    }
		    else {
			PM_UNLOCK(ctxp->c_pmcd->pc_lock);
			if (n != PM_ERR_TIMEOUT)
			    n = PM_ERR_IPC;
		    }
		    if (pinpdu > 0)
			__pmUnpinPDUBuf(pb);
		} while (n > 0);

		if (n == 0)
		    n |= changed;
	    }
	    else
		PM_UNLOCK(ctxp->c_pmcd->pc_lock);
	}
	else if (ctxp->c_type == PM_CONTEXT_LOCAL) {
	    n = __pmFetchLocal(ctxp, numpmid, pmidlist, result);
	}
	else {
	    /* assume PM_CONTEXT_ARCHIVE */
	    n = __pmLogFetch(ctxp, numpmid, pmidlist, result);
	    if (n >= 0 && (ctxp->c_mode & __PM_MODE_MASK) != PM_MODE_INTERP) {
		ctxp->c_origin.tv_sec = (__int32_t)(*result)->timestamp.tv_sec;
		ctxp->c_origin.tv_usec = (__int32_t)(*result)->timestamp.tv_usec;
	    }
	}

	/* process derived metrics, if any */
	if (have_dm) {
	    __pmFinishResult(ctxp, n, result);
	    if (newlist != NULL)
		free(newlist);
	}
	PM_UNLOCK(ctxp->c_lock);
    }

done:
#ifdef PCP_DEBUG
    if (pmDebug & DBG_TRACE_FETCH) {
	fprintf(stderr, "pmFetch returns ...\n");
	if (n > 0) {
	    fprintf(stderr, "PMCD state changes: agent(s)");
	    if (n & PMCD_ADD_AGENT) fprintf(stderr, " added");
	    if (n & PMCD_RESTART_AGENT) fprintf(stderr, " restarted");
	    if (n & PMCD_DROP_AGENT) fprintf(stderr, " dropped");
	    fputc('\n', stderr);
	}
	if (n >= 0)
	    __pmDumpResult(stderr, *result);
	else {
	    char	errmsg[PM_MAXERRMSGLEN];
	    fprintf(stderr, "Error: %s\n", pmErrStr_r(n, errmsg, sizeof(errmsg)));
	}
    }
#endif

    return n;
}
Esempio n. 5
0
int
DoFetch(ClientInfo *cip, __pmPDU* pb)
{
    int			i, j;
    int 		sts;
    int			ctxnum;
    __pmTimeval		when;
    int			nPmids;
    pmID		*pmidList;
    static pmResult	*endResult = NULL;
    static int		maxnpmids = 0;	/* sizes endResult */
    DomPmidList		*dList;		/* NOTE: NOT indexed by agent index */
    static int		nDoms = 0;
    static pmResult	**results = NULL;
    static int		*resIndex = NULL;
    __pmFdSet		waitFds;
    __pmFdSet		readyFds;
    int			nWait;
    int			maxFd;
    struct timeval	timeout;

    if (nAgents > nDoms) {
	if (results != NULL)
	    free(results);
	if (resIndex != NULL)
	    free(resIndex);
	results = (pmResult **)malloc((nAgents + 1) * sizeof (pmResult *));
	resIndex = (int *)malloc((nAgents + 1) * sizeof(int));
	if (results == NULL || resIndex == NULL) {
	    __pmNoMem("DoFetch.results", (nAgents + 1) * sizeof (pmResult *) + (nAgents + 1) * sizeof(int), PM_FATAL_ERR);
	}
	nDoms = nAgents;
    }
    memset(results, 0, (nAgents + 1) * sizeof(results[0]));

    sts = __pmDecodeFetch(pb, &ctxnum, &when, &nPmids, &pmidList);
    if (sts < 0)
	return sts;

    /* Check that a profile has been received from the specified context */
    if (ctxnum < 0 || ctxnum >= cip->szProfile ||
	cip->profile[ctxnum] == NULL) {
	__pmUnpinPDUBuf(pb);
	if (ctxnum < 0 || ctxnum >= cip->szProfile)
	    __pmNotifyErr(LOG_ERR, "DoFetch: bad ctxnum=%d\n", ctxnum);
	else
	    __pmNotifyErr(LOG_ERR, "DoFetch: no profile for ctxnum=%d\n", ctxnum);
	return PM_ERR_NOPROFILE;
    }

    if (nPmids > maxnpmids) {
	int		need;
	if (endResult != NULL)
	    free(endResult);
	need = (int)sizeof(pmResult) + (nPmids - 1) * (int)sizeof(pmValueSet *);
	if ((endResult = (pmResult *)malloc(need)) == NULL) {
	    __pmNoMem("DoFetch.endResult", need, PM_FATAL_ERR);
	}
	maxnpmids = nPmids;
    }

    dList = SplitPmidList(nPmids, pmidList);

    /* For each domain in the split pmidList, dispatch the per-domain subset
     * of pmIDs to the appropriate agent.  For DSO agents, the pmResult will
     * come back immediately.  If a request cannot be sent to an agent, a
     * suitable pmResult (containing metric not available values) will be
     * returned.
     */
    __pmFD_ZERO(&waitFds);
    nWait = 0;
    maxFd = -1;
    for (i = 0; dList[i].domain != -1; i++) {
	j = mapdom[dList[i].domain];
	results[j] = SendFetch(&dList[i], &agent[j], cip, ctxnum);
	if (results[j] == NULL) { /* Wait for agent's response */
	    int fd = agent[j].outFd;
	    agent[j].status.busy = 1;
	    __pmFD_SET(fd, &waitFds);
	    if (fd > maxFd)
		maxFd = fd;
	    nWait++;
	}
    }
    /* Construct pmResult for bad-pmID list */
    if (dList[i].listSize != 0)
	results[nAgents] = MakeBadResult(dList[i].listSize, dList[i].list, PM_ERR_NOAGENT);

    /* Wait for results to roll in from agents */
    while (nWait > 0) {
        __pmFD_COPY(&readyFds, &waitFds);
	if (nWait > 1) {
	    timeout.tv_sec = _pmcd_timeout;
	    timeout.tv_usec = 0;

            retry:
	    setoserror(0);
	    sts = __pmSelectRead(maxFd+1, &readyFds, &timeout);

	    if (sts == 0) {
		__pmNotifyErr(LOG_INFO, "DoFetch: select timeout");

		/* Timeout, terminate agents with undelivered results */
		for (i = 0; i < nAgents; i++) {
		    if (agent[i].status.busy) {
			/* Find entry in dList for this agent */
			for (j = 0; dList[j].domain != -1; j++)
			    if (dList[j].domain == agent[i].pmDomainId)
				break;
			results[i] = MakeBadResult(dList[j].listSize,
						   dList[j].list,
						   PM_ERR_NOAGENT);
			pmcd_trace(TR_RECV_TIMEOUT, agent[i].outFd, PDU_RESULT, 0);
			CleanupAgent(&agent[i], AT_COMM, agent[i].inFd);
		    }
		}
		break;
	    }
	    else if (sts < 0) {
		if (neterror() == EINTR)
		    goto retry;
		/* this is not expected to happen! */
		__pmNotifyErr(LOG_ERR, "DoFetch: fatal select failure: %s\n",
			netstrerror());
		Shutdown();
		exit(1);
	    }
	}

	/* Read results from agents that have them ready */
	for (i = 0; i < nAgents; i++) {
	    AgentInfo	*ap = &agent[i];
	    int		pinpdu;
	    if (!ap->status.busy || !__pmFD_ISSET(ap->outFd, &readyFds))
		continue;
	    ap->status.busy = 0;
	    __pmFD_CLR(ap->outFd, &waitFds);
	    nWait--;
	    pinpdu = sts = __pmGetPDU(ap->outFd, ANY_SIZE, _pmcd_timeout, &pb);
	    if (sts > 0)
		pmcd_trace(TR_RECV_PDU, ap->outFd, sts, (int)((__psint_t)pb & 0xffffffff));
	    if (sts == PDU_RESULT) {
		if ((sts = __pmDecodeResult(pb, &results[i])) >= 0)
		    if (results[i]->numpmid != aFreq[i]) {
			pmFreeResult(results[i]);
			sts = PM_ERR_IPC;
#ifdef PCP_DEBUG
			if (pmDebug & DBG_TRACE_APPL0)
			    __pmNotifyErr(LOG_ERR, "DoFetch: \"%s\" agent given %d pmIDs, returned %d\n",
					 ap->pmDomainLabel, aFreq[i], results[i]->numpmid);
#endif
		    }
	    }
	    else {
		if (sts == PDU_ERROR) {
		    int s;
		    if ((s = __pmDecodeError(pb, &sts)) < 0)
			sts = s;
		    else if (sts >= 0)
			sts = PM_ERR_GENERIC;
		    pmcd_trace(TR_RECV_ERR, ap->outFd, PDU_RESULT, sts);
		}
		else if (sts >= 0) {
		    pmcd_trace(TR_WRONG_PDU, ap->outFd, PDU_RESULT, sts);
		    sts = PM_ERR_IPC;
		}
	    }
	    if (pinpdu > 0)
		__pmUnpinPDUBuf(pb);

	    if (sts < 0) {
		/* Find entry in dList for this agent */
		for (j = 0; dList[j].domain != -1; j++)
		    if (dList[j].domain == agent[i].pmDomainId)
			break;
		results[i] = MakeBadResult(dList[j].listSize,
					   dList[j].list, sts);

		if (sts == PM_ERR_PMDANOTREADY) {
		    /* the agent is indicating it can't handle PDUs for now */
		    int k;
		    extern int CheckError(AgentInfo *ap, int sts);

		    for (k = 0; k < dList[j].listSize; k++)
			results[i]->vset[k]->numval = PM_ERR_AGAIN;
		    sts = CheckError(&agent[i], sts);
		}

#ifdef PCP_DEBUG
		if (pmDebug & DBG_TRACE_APPL0) {
		    fprintf(stderr, "RESULT error from \"%s\" agent : %s\n",
			    ap->pmDomainLabel, pmErrStr(sts));
		}
#endif
		if (sts == PM_ERR_IPC || sts == PM_ERR_TIMEOUT)
		    CleanupAgent(ap, AT_COMM, ap->outFd);
	    }
	}
    }

    endResult->numpmid = nPmids;
    __pmtimevalNow(&endResult->timestamp);
    /* The order of the pmIDs in the per-domain results is the same as in the
     * original request, but on a per-domain basis.  resIndex is an array of
     * indices (one per agent) of the next metric to be retrieved from each
     * per-domain result's vset.
     */
    memset(resIndex, 0, (nAgents + 1) * sizeof(resIndex[0]));

    for (i = 0; i < nPmids; i++) {
	j = mapdom[((__pmID_int *)&pmidList[i])->domain];
	endResult->vset[i] = results[j]->vset[resIndex[j]++];
    }
    pmcd_trace(TR_XMIT_PDU, cip->fd, PDU_RESULT, endResult->numpmid);

    sts = 0;
    if (cip->status.changes) {
	/* notify client of PMCD state change */
	sts = __pmSendError(cip->fd, FROM_ANON, (int)cip->status.changes);
	if (sts > 0)
	    sts = 0;
	cip->status.changes = 0;
    }
    if (sts == 0)
	sts = __pmSendResult(cip->fd, FROM_ANON, endResult);

    if (sts < 0) {
	pmcd_trace(TR_XMIT_ERR, cip->fd, PDU_RESULT, sts);
	CleanupClient(cip, sts);
    }

    /*
     * pmFreeResult() all the accumulated results.
     */
    for (i = 0; dList[i].domain != -1; i++) {
	j = mapdom[dList[i].domain];
	if (agent[j].ipcType == AGENT_DSO && agent[j].status.connected &&
	    !agent[j].status.madeDsoResult)
	    /* Living DSO's manage their own pmResult skeleton unless
	     * MakeBadResult was called to create the result.  The value sets
	     * within the skeleton need to be freed though!
	     */
	    __pmFreeResultValues(results[j]);
	else
	    /* For others it is dynamically allocated in __pmDecodeResult or
	     * MakeBadResult
	     */
	    pmFreeResult(results[j]);
    }
    if (results[nAgents] != NULL)
	pmFreeResult(results[nAgents]);
    __pmUnpinPDUBuf(pmidList);
    return 0;
}
Esempio n. 6
0
File: summary.c Progetto: Aconex/pcp
void
service_client(__pmPDU *pb)
{
    int		n;
    int		i;
    int		j;
    pmDesc	desc;
    pmDesc	foundDesc;
    pmResult	*resp;
    pmValueSet	*vsp;
    __pmPDUHdr   *ph = (__pmPDUHdr *)pb;

    switch (ph->type) {

    case PDU_DESC:
	if ((n = __pmDecodeDesc(pb, &desc)) < 0) {
	    fprintf(stderr, "service_client: __pmDecodeDesc failed: %s\n",
                    pmErrStr(n));
	    exit(1);
	}

	if (desc.indom != PM_INDOM_NULL) {
	    fprintf(stderr, "service_client: Warning: ignored desc for pmid=%s: indom is not singular\n", pmIDStr(desc.pmid));
	    return;
	}

	if (summary_desc(desc.pmid, &foundDesc, NULL) == 0) {
	    /* already in table */
	    fprintf(stderr,
                    "service_client: Warning: duplicate desc for pmid=%s\n",
                    pmIDStr(desc.pmid));
	    return;
	}

	nmeta++;
	if ((meta = (meta_t *)realloc(meta, nmeta * sizeof(meta_t))) == NULL) {
	    __pmNoMem("service_client: meta realloc", nmeta * sizeof(meta_t), PM_FATAL_ERR);
	}
	memcpy(&meta[nmeta-1].desc, &desc, sizeof(pmDesc));

	break;

    case PDU_RESULT:
	if ((n = __pmDecodeResult(pb, &resp)) < 0) {
	    fprintf(stderr, "service_client: __pmDecodeResult failed: %s\n", pmErrStr(n));
	    exit(1);
	}

	if (cachedResult == NULL) {
	    int		need;
	    need = (int)sizeof(pmResult) - (int)sizeof(pmValueSet *);
	    if ((cachedResult = (pmResult *)malloc(need)) == NULL) {
		__pmNoMem("service_client: result malloc", need, PM_FATAL_ERR);
	    }
	    cachedResult->numpmid = 0;
	}

	/*
	 * swap values from resp with those in cachedResult, expanding
	 * cachedResult if there are metrics we've not seen before
	 */
	for (i = 0; i < resp->numpmid; i++) {
	    for (j = 0; j < cachedResult->numpmid; j++) {
		if (resp->vset[i]->pmid == cachedResult->vset[j]->pmid) {
		    /* found matching PMID, update this value */
		    break;
		}
	    }

	    if (j == cachedResult->numpmid) {
		/* new PMID, expand cachedResult and initialize vset */
		int		need;
		cachedResult->numpmid++;
		need = (int)sizeof(pmResult) +
		    (cachedResult->numpmid-1) * (int)sizeof(pmValueSet *);
		if ((cachedResult = (pmResult *)realloc(cachedResult, need)) == NULL) {
		    __pmNoMem("service_client: result realloc", need, PM_FATAL_ERR);
		}
		if ((cachedResult->vset[j] = (pmValueSet *)malloc(sizeof(pmValueSet))) == NULL) {
		    __pmNoMem("service_client: vset[]", sizeof(pmValueSet), PM_FATAL_ERR);
		}
		cachedResult->vset[j]->pmid = resp->vset[i]->pmid;
		cachedResult->vset[j]->numval = 0;
	    }

	    /*
	     * swap vsets
	     */
	    vsp = cachedResult->vset[j];
	    cachedResult->vset[j] = resp->vset[i];
	    resp->vset[i] = vsp;

	}

	pmFreeResult(resp);
	break;
	    
    case PDU_ERROR:
	if ((n = __pmDecodeError(pb, &i)) < 0) {
	    fprintf(stderr, "service_client: __pmDecodeError failed: %s\n", pmErrStr(n));
	    exit(1);
	}
	fprintf(stderr, "service_client: Error PDU! %s\n", pmErrStr(i));
	break;
    
    default:
	fprintf(stderr, "service_client: Bogus PDU type %d\n", ph->type);
	exit(1);
    }
}
Esempio n. 7
0
/* Process I/O on file descriptors from agents that were marked as not ready
 * to handle PDUs.
 */
static int
HandleReadyAgents(__pmFdSet *readyFds)
{
    int		i, s, sts;
    int		fd;
    int		reason;
    int		ready = 0;
    AgentInfo	*ap;
    __pmPDU	*pb;

    for (i = 0; i < nAgents; i++) {
	ap = &agent[i];
	if (ap->status.notReady) {
	    fd = ap->outFd;
	    if (__pmFD_ISSET(fd, readyFds)) {
		int		pinpdu;

		/* Expect an error PDU containing PM_ERR_PMDAREADY */
		reason = AT_COMM;	/* most errors are protocol failures */
		pinpdu = sts = __pmGetPDU(ap->outFd, ANY_SIZE, _pmcd_timeout, &pb);
		if (sts > 0)
		    pmcd_trace(TR_RECV_PDU, ap->outFd, sts, (int)((__psint_t)pb & 0xffffffff));
		if (sts == PDU_ERROR) {
		    s = __pmDecodeError(pb, &sts);
		    if (s < 0) {
			sts = s;
			pmcd_trace(TR_RECV_ERR, ap->outFd, PDU_ERROR, sts);
		    }
		    else {
			/* sts is the status code from the error PDU */
			if (pmDebug & DBG_TRACE_APPL0)
			    __pmNotifyErr(LOG_INFO,
				 "%s agent (not ready) sent %s status(%d)\n",
				 ap->pmDomainLabel,
				 sts == PM_ERR_PMDAREADY ?
					     "ready" : "unknown", sts);
			if (sts == PM_ERR_PMDAREADY) {
			    ap->status.notReady = 0;
			    sts = 1;
			    ready++;
			}
			else {
			    pmcd_trace(TR_RECV_ERR, ap->outFd, PDU_ERROR, sts);
			    sts = PM_ERR_IPC;
			}
		    }
		}
		else {
		    if (sts < 0)
			pmcd_trace(TR_RECV_ERR, ap->outFd, PDU_RESULT, sts);
		    else
			pmcd_trace(TR_WRONG_PDU, ap->outFd, PDU_ERROR, sts);
 		    sts = PM_ERR_IPC; /* Wrong PDU type */
		}
		if (pinpdu > 0)
		    __pmUnpinPDUBuf(pb);

		if (ap->ipcType != AGENT_DSO && sts <= 0)
		    CleanupAgent(ap, reason, fd);
	    }
	}
    }
    return ready;
}