Example #1
0
int
__pmSendInstanceReq(int fd, int from, const __pmTimeval *when, pmInDom indom, 
		    int inst, const char *name)
{
    instance_req_t	*pp;
    int			need;
    int			sts;

    need = sizeof(instance_req_t) - sizeof(int);
    if (name != NULL)
	need += PM_PDU_SIZE_BYTES(strlen(name));
    if ((pp = (instance_req_t *)__pmFindPDUBuf(need)) == NULL)
	return -oserror();
    pp->hdr.len = need;
    pp->hdr.type = PDU_INSTANCE_REQ;
    pp->hdr.from = from;
    pp->when.tv_sec = htonl((__int32_t)when->tv_sec);
    pp->when.tv_usec = htonl((__int32_t)when->tv_usec);
    pp->indom = __htonpmInDom(indom);
    pp->inst = htonl(inst);
    if (name == NULL)
	pp->namelen = 0;
    else {
	pp->namelen = (int)strlen(name);
	memcpy((void *)pp->name, (void *)name, pp->namelen);
	if ((pp->namelen % sizeof(__pmPDU)) != 0) {
            /* clear the padding bytes, lest they contain garbage */
	    int	pad;
	    char	*padp = pp->name + pp->namelen;

	    for (pad = sizeof(__pmPDU) - 1; pad >= (pp->namelen % sizeof(__pmPDU)); pad--)
		*padp++ = '~';	/* buffer end */
	}
	pp->namelen = htonl(pp->namelen);
    }

    sts = __pmXmitPDU(fd, (__pmPDU *)pp);
    __pmUnpinPDUBuf(pp);
    return sts;
}
Example #2
0
int
__pmSendText(int fd, int ctx, int ident, const char *buffer)
{
    text_t	*pp;
    size_t	need;
    size_t	len = strlen(buffer);
    int		sts;

    need = sizeof(text_t) - sizeof(pp->buffer) + PM_PDU_SIZE_BYTES(len);
    if ((pp = (text_t *)__pmFindPDUBuf((int)need)) == NULL)
	return -oserror();
    pp->hdr.len = (int)need;
    pp->hdr.type = PDU_TEXT;
    pp->hdr.from = ctx;
    /*
     * Note: ident argument must already be in network byte order.
     * The caller has to do this because the type of ident is not
     * part of the transmitted PDU_TEXT pdu; ident may be either
     * a pmID or pmInDom, and so the caller must use either
     * __htonpmID or __htonpmInDom (respectively).
     */
    pp->ident = ident;
    pp->buflen = htonl(len);
    memcpy((void *)pp->buffer, (void *)buffer, len);
    if (len % sizeof(__pmPDU) != 0) {
	/* clear the padding bytes, lest they contain garbage */
	int	pad;
	char	*padp = pp->buffer + len;
	for (pad = sizeof(__pmPDU) - 1; pad >= (len % sizeof(__pmPDU)); pad--)
	    *padp++ = '~';	/* buffer end */
    }

    sts = __pmXmitPDU(fd, (__pmPDU *)pp);
    __pmUnpinPDUBuf(pp);
    return sts;
}
Example #3
0
static int
do_size(pmResult *rp)
{
    int		nbyte = 0;
    int		i;
    int		j;
    /*
     *  Externally the log record looks like this ...
     *  :----------:-----------:..........:---------:
     *  | int len  | timestamp | pmResult | int len |
     *  :----------:-----------:..........:---------:
     *
     * start with sizes of the header len, timestamp, numpmid, and
     * trailer len
     */
    nbyte = sizeof(int) + sizeof(__pmTimeval) + sizeof(int);
    						/* len + timestamp + len */
    nbyte += sizeof(int);
    							/* numpmid */
    for (i = 0; i < rp->numpmid; i++) {
	pmValueSet	*vsp = rp->vset[i];
	nbyte += sizeof(pmID) + sizeof(int);		/* + pmid[i], numval */
	if (vsp->numval > 0) {
	    nbyte += sizeof(int);			/* + valfmt */
	    for (j = 0; j < vsp->numval; j++) {
		nbyte += sizeof(__pmValue_PDU);		/* + pmValue[j] */
		if (vsp->valfmt != PM_VAL_INSITU)
							/* + pmValueBlock */
							/* rounded up */
		    nbyte += PM_PDU_SIZE_BYTES(vsp->vlist[j].value.pval->vlen);
	    }
	}
    }

    return nbyte;
}
Example #4
0
File: events.c Project: Aconex/pcp
/*
 * Handle event records.
 *
 * Walk the packed array of events using similar logic to
 * pmUnpackEventRecords() but we don't need any allocations.
 *
 * For each embedded event parameter, make sure the metadata for
 * the associated metric is added to the archive.
 */
int
do_events(pmValueSet *vsp)
{
    pmEventArray	*eap;
    char		*base;
    pmEventRecord	*erp;
    pmEventParameter	*epp;
    int			r;	/* records */
    int			p;	/* parameters in a record ... */
    int			i;	/* instances ... */
    int			sts;
    pmDesc		desc;

    for (i = 0; i < vsp->numval; i++) {
	if ((sts = __pmCheckEventRecords(vsp, i)) < 0) {
	    __pmDumpEventRecords(stderr, vsp, i);
	    return sts;
	}
	eap = (pmEventArray *)vsp->vlist[i].value.pval;
	if (eap->ea_nrecords == 0)
	    return 0;
	base = (char *)&eap->ea_record[0];
	for (r = 0; r < eap->ea_nrecords; r++) {
	    erp = (pmEventRecord *)base;
	    base += sizeof(erp->er_timestamp) + sizeof(erp->er_flags) + sizeof(erp->er_nparams);
	    if (erp->er_flags & PM_EVENT_FLAG_MISSED) {
		/*
		 * no event "parameters" here, just a missed records count
		 * in er_nparams
		 */
		continue;
	    }
	    for (p = 0; p < erp->er_nparams; p++) {
		epp = (pmEventParameter *)base;
		base += sizeof(epp->ep_pmid) + PM_PDU_SIZE_BYTES(epp->ep_len);
		sts = __pmLogLookupDesc(&logctl, epp->ep_pmid, &desc);
		if (sts < 0) {
		    int	numnames;
		    char	**names;
		    numnames = pmNameAll(epp->ep_pmid, &names);
		    if (numnames < 0) {
			/*
			 * Event parameter metric not defined in the PMNS.
			 * This should not happen, but is probably not fatal, so
			 * issue a warning and make up a name based on the pmid
			 * event_param.<domain>.<cluster>.<item>
			 */
			char	*name;
                        size_t   name_size = strlen("event_param")+3+1+4+1+4+1;
                        names = (char **)malloc(sizeof(char*) + name_size);
			if (names == NULL)
			    return -oserror();
			name = (char *)&names[1];
			names[0] = name;
			snprintf(name, name_size, "event_param.%s", pmIDStr(epp->ep_pmid));
			fprintf(stderr, "Warning: metric %s has no name, using %s\n", pmIDStr(epp->ep_pmid), name);
		    }
		    sts = pmLookupDesc(epp->ep_pmid, &desc);
		    if (sts < 0) {
			/* Event parameter metric does not have a pmDesc.
			 * This should not happen, but is probably not entirely
			 * fatal (although more serious than not having a metric
			 * name), issue a warning and construct a minimalist
			 * pmDesc
			 */
			desc.pmid = epp->ep_pmid;
			desc.type = PM_TYPE_AGGREGATE;
			desc.indom = PM_INDOM_NULL;
			desc.sem = PM_SEM_DISCRETE;
			memset(&desc.units, '\0', sizeof(desc.units));
			fprintf(stderr, "Warning: metric %s (%s) has no descriptor, using a default one\n", names[0], pmIDStr(epp->ep_pmid));
		    }
		    if ((sts = __pmLogPutDesc(&logctl, &desc, numnames, names)) < 0) {
			fprintf(stderr, "__pmLogPutDesc: %s\n", pmErrStr(sts));
			exit(1);
		    }
		    free(names);
		}
	    }
	}
    }
    return 0;
}
Example #5
0
int
__pmDecodeInstance(__pmPDU *pdubuf, __pmInResult **result)
{
    int			i;
    int			j;
    instance_t		*rp;
    instlist_t		*ip;
    __pmInResult	*res;
    int			sts;
    char		*p;
    char		*pdu_end;
    int			keep_instlist;
    int			keep_namelist;

    rp = (instance_t *)pdubuf;
    pdu_end = (char *)pdubuf + rp->hdr.len;

    if (pdu_end - (char *)pdubuf < sizeof(instance_t) - sizeof(__pmPDU))
	return PM_ERR_IPC;

    if ((res = (__pmInResult *)malloc(sizeof(*res))) == NULL)
	return -oserror();
    res->instlist = NULL;
    res->namelist = NULL;
    res->indom = __ntohpmInDom(rp->indom);
    res->numinst = ntohl(rp->numinst);

    if (res->numinst >= (INT_MAX / sizeof(res->instlist[0])) ||
	res->numinst >= (INT_MAX / sizeof(res->namelist[0])) ||
	res->numinst >= rp->hdr.len) {
	sts = PM_ERR_IPC;
	goto badsts;
    }
    if ((res->instlist = (int *)malloc(res->numinst * sizeof(res->instlist[0]))) == NULL) {
	sts = -oserror();
	goto badsts;
    }
    if ((res->namelist = (char **)malloc(res->numinst * sizeof(res->namelist[0]))) == NULL) {
	sts = -oserror();
	goto badsts;
    }
    /* required for __pmFreeInResult() in the event of a later error */
    memset(res->namelist, 0, res->numinst * sizeof(res->namelist[0]));

    if (res->numinst == 1)
	keep_instlist = keep_namelist = 0;
    else
	keep_instlist = keep_namelist = 1;

    for (i = j = 0; i < res->numinst; i++) {
	ip = (instlist_t *)&rp->rest[j/sizeof(__pmPDU)];
	if (sizeof(instlist_t) - sizeof(ip->name) > (size_t)(pdu_end - (char *)ip)) {
	    sts = PM_ERR_IPC;
	    goto badsts;
	}

	res->instlist[i] = ntohl(ip->inst);
	if (res->instlist[i] != PM_IN_NULL)
	    keep_instlist = 1;
	ip->namelen = ntohl(ip->namelen);
	if (ip->namelen > 0)
	    keep_namelist = 1;
	if (ip->namelen < 0) {
	    sts = PM_ERR_IPC;
	    goto badsts;
	}
	if (sizeof(instlist_t) - sizeof(int) + ip->namelen > (size_t)(pdu_end - (char *)ip)) {
	    sts = PM_ERR_IPC;
	    goto badsts;
	}
	if ((p = (char *)malloc(ip->namelen + 1)) == NULL) {
	    sts = -oserror();
	    goto badsts;
	}
	memcpy((void *)p, (void *)ip->name, ip->namelen);
	p[ip->namelen] = '\0';
	res->namelist[i] = p;
	j += sizeof(*ip) - sizeof(ip->name) + PM_PDU_SIZE_BYTES(ip->namelen);
    }
    if (keep_instlist == 0) {
	free(res->instlist);
	res->instlist = NULL;
    }
    if (keep_namelist == 0) {
	free(res->namelist[0]);
	free(res->namelist);
	res->namelist = NULL;
    }

#ifdef PCP_DEBUG
    if (pmDebug & DBG_TRACE_INDOM)
	__pmDumpInResult(stderr, res);
#endif
    *result = res;
    return 0;

badsts:
    __pmFreeInResult(res);
    return sts;
}
Example #6
0
int
__pmSendInstance(int fd, int from, __pmInResult *result)
{
    instance_t	*rp;
    instlist_t		*ip;
    int			need;
    int			i;
    int			j;
    int			sts;

#ifdef PCP_DEBUG
    if (pmDebug & DBG_TRACE_INDOM)
	__pmDumpInResult(stderr, result);
#endif

    need = sizeof(*rp) - sizeof(rp->rest);
    /* instlist_t + name rounded up to a __pmPDU boundary */
    for (i = 0; i < result->numinst; i++) {
	need += sizeof(*ip) - sizeof(ip->name);
	if (result->namelist != NULL)
	    need += PM_PDU_SIZE_BYTES(strlen(result->namelist[i]));
    }

    if ((rp = (instance_t *)__pmFindPDUBuf(need)) == NULL)
	return -oserror();
    rp->hdr.len = need;
    rp->hdr.type = PDU_INSTANCE;
    rp->hdr.from = from;
    rp->indom = __htonpmInDom(result->indom);
    rp->numinst = htonl(result->numinst);

    for (i = j = 0; i < result->numinst; i++) {
	ip = (instlist_t *)&rp->rest[j/sizeof(__pmPDU)];
	if (result->instlist != NULL)
	    ip->inst = htonl(result->instlist[i]);
	else
	    /* weird, but this is going to be ignored at the other end */
	    ip->inst = htonl(PM_IN_NULL);
	if (result->namelist != NULL) {
	    ip->namelen = (int)strlen(result->namelist[i]);
	    memcpy((void *)ip->name, (void *)result->namelist[i], ip->namelen);
	    if ((ip->namelen % sizeof(__pmPDU)) != 0) {
                /* clear the padding bytes, lest they contain garbage */
		int	pad;
		char	*padp = ip->name + ip->namelen;
		for (pad = sizeof(__pmPDU) - 1; pad >= (ip->namelen % sizeof(__pmPDU)); pad--)
		    *padp++ = '~';	/* buffer end */
	    }
	    j += sizeof(*ip) - sizeof(ip->name) + PM_PDU_SIZE_BYTES(ip->namelen);
	    ip->namelen = htonl(ip->namelen);
	}
	else {
	    ip->namelen = 0;
	    j += sizeof(*ip) - sizeof(ip->name);
	}
    }

    sts = __pmXmitPDU(fd, (__pmPDU *)rp);
    __pmUnpinPDUBuf(rp);
    return sts;
}