Exemple #1
0
static void
dumpDesc(__pmContext *ctxp)
{
    int			i;
    int			sts;
    char		**names;
    __pmHashNode	*hp;
    pmDesc		*dp;

    printf("\nDescriptions for Metrics in the Log ...\n");
    for (i = 0; i < ctxp->c_archctl->ac_log->l_hashpmid.hsize; i++) {
	for (hp = ctxp->c_archctl->ac_log->l_hashpmid.hash[i]; hp != NULL; hp = hp->next) {
	    dp = (pmDesc *)hp->data;
	    sts = pmNameAll(dp->pmid, &names);
	    if (sts < 0)
		printf("PMID: %s (%s)\n", pmIDStr(dp->pmid), "<noname>");
	    else {
		printf("PMID: %s (", pmIDStr(dp->pmid));
		__pmPrintMetricNames(stdout, sts, names, " or ");
		printf(")\n");
		free(names);
	    }
	    __pmPrintDesc(stdout, dp);
	}
    }
}
Exemple #2
0
static void
print_metric(FILE *f, pmID pmid)
{
    int		numnames;
    char	**names;

    if ((numnames = pmNameAll(pmid, &names)) < 1)
	fprintf(f, "%s", pmIDStr(pmid));
    else {
	__pmPrintMetricNames(f, numnames, names, " or ");
	free(names);
    }
}
Exemple #3
0
void
_dbDumpResult(FILE *f, pmResult *resp, pmDesc *desc_list)
{
    int		i;
    int		j;
    int		n;
    char	**names;

    fprintf(f, "pmResult dump from " PRINTF_P_PFX "%p timestamp: %d.%06d ",
        resp, (int)resp->timestamp.tv_sec, (int)resp->timestamp.tv_usec);
    pmPrintStamp(f, &resp->timestamp);
    fprintf(f, " numpmid: %d\n", resp->numpmid);
    for (i = 0; i < resp->numpmid; i++) {
	pmValueSet	*vsp = resp->vset[i];
	names = NULL; /* silence coverity */
	n = pmNameAll(vsp->pmid, &names);
	if (n < 0)
	    fprintf(f, "  %s (%s):", pmIDStr(vsp->pmid), "<noname>");
	else {
	    fprintf(f, "  %s (", pmIDStr(vsp->pmid));
	    __pmPrintMetricNames(f, n, names, " or ");
	    fprintf(f, "):");
	    free(names);
	}
	if (vsp->numval == 0) {
	    fprintf(f, " No values returned!\n");
	    continue;
	}
	else if (vsp->numval < 0) {
	    fprintf(f, " %s\n", pmErrStr(vsp->numval));
	    continue;
	}
	fprintf(f, " numval: %d", vsp->numval);
	fprintf(f, " valfmt: %d vlist[]:\n", vsp->valfmt);
	for (j = 0; j < vsp->numval; j++) {
	    pmValue	*vp = &vsp->vlist[j];
	    if (vsp->numval > 1 || desc_list[i].indom != PM_INDOM_NULL) {
		fprintf(f, "    inst [%d", vp->inst);
		fprintf(f, " or ???]");
		fputc(' ', f);
	    }
	    else
		fprintf(f, "   ");
	    fprintf(f, "value ");
	    pmPrintValue(f, vsp->valfmt, desc_list[i].type, vp, 1);
	    fputc('\n', f);
	}/*for*/
    }/*for*/
}/*_dbDumpResult*/
Exemple #4
0
static void
dump_parameter(pmValueSet *xvsp, int index, int *flagsp)
{
    int		sts, flags = *flagsp;
    pmDesc	desc;
    char	**names;

    if ((sts = pmNameAll(xvsp->pmid, &names)) >= 0) {
	if (index == 0) {
	    if (xvsp->pmid == pmid_flags) {
		flags = *flagsp = xvsp->vlist[0].value.lval;
		printf(" flags 0x%x", flags);
		printf(" (%s) ---\n", pmEventFlagsStr(flags));
		free(names);
		return;
	    }
	    printf(" ---\n");
	}
	if ((flags & PM_EVENT_FLAG_MISSED) && index == 1 &&
	    (xvsp->pmid == pmid_missed)) {
	    printf("              ==> %d missed event records\n",
		    xvsp->vlist[0].value.lval);
	    free(names);
	    return;
	}
	printf("                %s (", pmIDStr(xvsp->pmid));
	__pmPrintMetricNames(stdout, sts, names, " or ");
	printf("):");
	free(names);
    }
    else
	printf("	            PMID: %s:", pmIDStr(xvsp->pmid));
    if ((sts = pmLookupDesc(xvsp->pmid, &desc)) < 0) {
	printf(" pmLookupDesc: %s\n", pmErrStr(sts));
	return;
    }
    printf(" value ");
    pmPrintValue(stdout, xvsp->valfmt, desc.type, &xvsp->vlist[0], 1);
    putchar('\n');
}
Exemple #5
0
static void
dump_result(pmResult *resp)
{
    int		i;
    int		j;
    int		n;
    char	**names;
    pmDesc	desc;

    if (sflag) {
	int		nbyte;
	nbyte = do_size(resp);
	printf("[%d bytes]\n", nbyte);
    }

    if (xflag) {
	char	       *ddmm;
	char	       *yr;

	ddmm = pmCtime(&resp->timestamp.tv_sec, timebuf);
	ddmm[10] = '\0';
	yr = &ddmm[20];
	printf("%s ", ddmm);
	__pmPrintStamp(stdout, &resp->timestamp);
	printf(" %4.4s", yr);
	if (xflag >= 2)
	    printf(" (%.6f)", __pmtimevalSub(&resp->timestamp, &label.ll_start));
    }
    else
	__pmPrintStamp(stdout, &resp->timestamp);

    if (resp->numpmid == 0) {
	printf("  <mark>\n");
	return;
    }

    for (i = 0; i < resp->numpmid; i++) {
	pmValueSet	*vsp = resp->vset[i];

	if (i > 0)
	    printf("            ");
	n = pmNameAll(vsp->pmid, &names);
	if (vsp->numval == 0) {
	    printf("  %s (", pmIDStr(vsp->pmid));
	    __pmPrintMetricNames(stdout, n, names, " or ");
	    printf("): No values returned!\n");
	    goto next;
	}
	else if (vsp->numval < 0) {
	    printf("  %s (", pmIDStr(vsp->pmid));
	    __pmPrintMetricNames(stdout, n, names, " or ");
	    printf("): %s\n", pmErrStr(vsp->numval));
	    goto next;
	}

	if (pmLookupDesc(vsp->pmid, &desc) < 0) {
	    /* don't know, so punt on the most common cases */
	    desc.indom = PM_INDOM_NULL;
	    if (vsp->valfmt == PM_VAL_INSITU)
		desc.type = PM_TYPE_32;
	    else
		desc.type = PM_TYPE_AGGREGATE;
	}

	for (j = 0; j < vsp->numval; j++) {
	    if (desc.type == PM_TYPE_EVENT ||
		desc.type == PM_TYPE_HIGHRES_EVENT)
		dump_event(n, names, vsp, j, desc.indom, desc.type);
	    else
		dump_metric(n, names, vsp, j, desc.indom, desc.type);
	}
next:
	if (n > 0)
	    free(names);
    }
}
Exemple #6
0
static void
foo(FILE *f, char *fn, int i, void *closure)
{
    int		sts;
    int		numnames;
    int		j;
    int		leaf;
    pmID	pmids[NMETRIC];
    char	**names;
    char	*name;
    int		*stsset;
    char	strbuf[20];

    if ((sts = pmLookupName(NMETRIC-i, &namelist[i], pmids)) < 0) {
	if (sts != PM_ERR_NONLEAF) {
	    fprintf(f, "%s: %s ...: pmLookupName Error: %s\n", fn, namelist[i], pmErrStr(sts));
	    pthread_exit("botch");
	}
    }
    for (j = i; j < NMETRIC; j++) {
	if (pmids[j-i] != pmidlist[j]) {
	    fprintf(f, "%s: %s: Botch: expecting %s", fn, namelist[j], pmIDStr_r(pmidlist[j], strbuf, sizeof(strbuf)));
	    fprintf(f, ", got %s\n", pmIDStr_r(pmids[j-i], strbuf, sizeof(strbuf)));
	    pthread_exit("botch");
	}
    }
    fprintf(f, "%s: %s ... pmLookupName OK\n", fn, namelist[i]);

    fprintf(f, "%s: %s", fn, namelist[i]);
    if (pmidlist[i] != PM_ID_NULL) {
	/* leaf node in PMNS */
	if ((numnames = pmNameAll(pmidlist[i], &names)) < 0) {
	    fprintf(f, "\n%s: %s ...: pmNameAll Error: %s\n", fn, namelist[i], pmErrStr(numnames));
	    pthread_exit("botch");
	}
	for (j = 0; j < numnames; j++) {
	    if (strcmp(names[j], namelist[i]) == 0)
		break;
	}
	if (j == numnames) {
	    fprintf(f, "\n%s: %s: Botch: expecting %s, got {", fn, pmIDStr_r(pmidlist[i], strbuf, sizeof(strbuf)), namelist[i]);
	    __pmPrintMetricNames(f, numnames, names, ",");
	    fprintf(f, "}\n");
	    pthread_exit("botch");
	}
	fprintf(f, " pmNameAll OK");
	if ((sts = pmNameID(pmidlist[i], &name)) < 0) {
	    fprintf(f, "\n%s: %s ...: pmNameID Error: %s\n", fn, namelist[i], pmErrStr(sts));
	    pthread_exit("botch");
	}
	for (j = 0; j < numnames; j++) {
	    if (strcmp(name, names[j]) == 0)
		break;
	}
	if (j == numnames) {
	    fprintf(f, "\n%s: %s: Botch: expecting one of {", fn, pmIDStr_r(pmidlist[i], strbuf, sizeof(strbuf)));
	    __pmPrintMetricNames(f, numnames, names, ",");
	    fprintf(f, "}, got %s\n", name);
	    pthread_exit("botch");
	}
	free(names);
	free(name);
	fprintf(f, " pmNameID OK");
    }
    else {
	/* non-leaf node in PMNS */
	int	keep = 0;
	if ((sts = pmGetChildrenStatus(namelist[i], &names, &stsset)) < 0) {
	    fprintf(f, "\n%s: %s ...: pmGetChildrenStatus Error: %s\n", fn, namelist[i], pmErrStr(sts));
	    pthread_exit("botch");
	}
	leaf = 0;
	for (j = 0; j < sts; j++) {
	    if (stsset[j] == PMNS_LEAF_STATUS) leaf++;
	}
	PM_LOCK(chn_lock);
	if (leaf_chn[i] == -1) {
	    leaf_chn[i] = leaf;
	    nonleaf_chn[i] = sts - leaf;
	    chn[i] = names;
	    keep = 1;
	}
	else {
	    if (leaf != leaf_chn[i] || sts - leaf != nonleaf_chn[i]) {
		fprintf(f, "\n%s: %s: Botch: expecting %d leaf & %d non-leaf, got %d leaf & %d non-leaf\n", fn, namelist[i], leaf_chn[i], nonleaf_chn[i], leaf, sts - leaf);
		pthread_exit("botch");
	    }
	    for (j = 0; j < sts; j++) {
		if (strcmp(chn[i][j], names[j]) != 0) {
		    fprintf(f, "\n%s: %s: Botch: child[%d] expecting %s, got %s\n", fn, namelist[i], j, chn[i][j], names[j]);
		    PM_UNLOCK(chn_lock);
		    pthread_exit("botch");
		}
	    }
	}
	if (keep == 0) {
	    free(names);
	    names = NULL; /* silence coverity */
	}
	free(stsset);
	fprintf(f, " pmGetChildrenStatus OK");
	if ((sts = pmGetChildren(namelist[i], &names)) < 0) {
	    fprintf(f, "\n%s: %s ...: pmGetChildren Error: %s\n", fn, namelist[i], pmErrStr(sts));
	    PM_UNLOCK(chn_lock);
	    pthread_exit("botch");
	}
	if (sts != leaf_chn[i] + nonleaf_chn[i]) {
	    fprintf(f, "\n%s: %s: Botch: expecting %d children, got %d\n", fn, namelist[i], leaf_chn[i] + nonleaf_chn[i], sts);
	    PM_UNLOCK(chn_lock);
	    pthread_exit("botch");
	}
	for (j = 0; j < sts; j++) {
	    if (strcmp(chn[i][j], names[j]) != 0) {
		fprintf(f, "\n%s: %s: Botch: child[%d] expecting %s, got %s\n", fn, namelist[i], j, chn[i][j], names[j]);
		PM_UNLOCK(chn_lock);
		pthread_exit("botch");
	    }
	}
	PM_UNLOCK(chn_lock);
	free(names);
	fprintf(f, " pmGetChildren OK");
	*((int *)closure) = 0;
	if ((sts = pmTraversePMNS_r(namelist[i], dometric, closure)) < 0) {
	    fprintf(f, "\n%s: %s ...: pmTraversePMNS_r Error: %s\n", fn, namelist[i], pmErrStr(sts));
	    pthread_exit("botch");
	}
	if (sum_traverse[i] != *((int *)closure)) {
	    fprintf(f, "\n%s: %s: Botch: sum strlen(descendent names) expecting %d, got %d\n", fn, namelist[i], sum_traverse[i], *((int *)closure));
	    pthread_exit("botch");
	}
	fprintf(f, " pmTraversePMNS_r OK");
    }
    fputc('\n', f);

}
Exemple #7
0
static int
do_control(__pmPDU *pb)
{
    int			sts;
    int			control;
    int			state;
    int			delta;
    pmResult		*request;
    pmResult		*result;
    int			siamised = 0;	/* the verb from siamese (as in twins) */
    int			i;
    int			j;
    int			val;
    pmValueSet		*vsp;
    optreq_t		*rqp;
    task_t		*tp;
    time_t		now;
    int			reqstate = 0;

    /*
     * TODO	- encoding for logging interval in requests and results?
     */
    if ((sts = __pmDecodeLogControl(pb, &request, &control, &state, &delta)) < 0)
	return sts;

#ifdef PCP_DEBUG
    if (pmDebug & DBG_TRACE_LOG) {
	fprintf(stderr, "do_control: control=%d state=%d delta=%d request ...\n",
		control, state, delta);
	dumpcontrol(stderr, request, 0);
    }
#endif

    if (control == PM_LOG_MANDATORY || control == PM_LOG_ADVISORY) {
	time(&now);
	fprintf(stderr, "\n%s", ctime(&now));
	fprintf(stderr, "pmlc request from %s: %s",
	    pmlc_host, control == PM_LOG_MANDATORY ? "mandatory" : "advisory");
	if (state == PM_LOG_ON) {
	    if (delta == 0)
		fprintf(stderr, " on once\n");
	    else
		fprintf(stderr, " on %.1f sec\n", (float)delta/1000);
	}
	else if (state == PM_LOG_OFF)
	    fprintf(stderr, " off\n");
	else
	    fprintf(stderr, " maybe\n");
    }

    /*
     * access control checks
     */
    sts = 0;
    switch (control) {
	case PM_LOG_MANDATORY:
	    if (denyops & PM_OP_LOG_MAND)
		sts = PM_ERR_PERMISSION;
	    break;

	case PM_LOG_ADVISORY:
	    if (denyops & PM_OP_LOG_ADV)
		sts = PM_ERR_PERMISSION;
	    break;

	case PM_LOG_ENQUIRE:
	    /*
	     * Don't need to check [access] as you have to have _some_
	     * permission (at least one of PM_OP_LOG_ADV or PM_OP_LOG_MAND
	     * and PM_OP_LOG_ENQ) to make a connection ... and if you
	     * have either PM_OP_LOG_ADV or PM_OP_LOG_MAND it makes no
	     * sense to deny PM_OP_LOG_ENQ operations.
	     */
	    break;

	default:
	    fprintf(stderr, "Bad control PDU type %d\n", control);
	    sts = PM_ERR_IPC;
	    break;
    }
    if (sts < 0) {
	fprintf(stderr, "Error: %s\n", pmErrStr(sts));
	if ((sts = __pmSendError(clientfd, FROM_ANON, sts)) < 0)
	    __pmNotifyErr(LOG_ERR,
			 "do_control: error sending Error PDU to client: %s\n",
			 pmErrStr(sts));
	pmFreeResult(request);
	return sts;
    }

    /* handle everything except PM_LOG_ENQUIRE */
    if (control == PM_LOG_MANDATORY || control == PM_LOG_ADVISORY) {
	/* update the logging status of metrics */

	task_t		*newtp = NULL; /* task for metrics/insts in request */
	struct timeval	tdelta = { 0 };
	int		newtask;
	int		mflags;

	/* convert state and control to the bitmask used in pmlogger and values
	 * returned in results.  Remember that reqstate starts with nothing on.
	 */
	if (state == PM_LOG_ON)
	    PMLC_SET_ON(reqstate, 1);
	else
	    PMLC_SET_ON(reqstate, 0);
	if (control == PM_LOG_MANDATORY) {
	    if (state == PM_LOG_MAYBE)
		/* mandatory+maybe => maybe+advisory+off  */
		PMLC_SET_MAYBE(reqstate, 1);
	    else
		PMLC_SET_MAND(reqstate, 1);
	}

	/* try to find an existing task for the request
	 * Never return a "once only" task, it may have gone off already and just
	 * be hanging around like a bad smell.
	 */
	if (delta != 0) {
	    tdelta.tv_sec = delta / 1000;
	    tdelta.tv_usec = (delta % 1000) * 1000;
	    newtp = find_task(reqstate, &tdelta);
	}
	newtask = (newtp == NULL);

	for (i = 0; i < request->numpmid; i++) {
	    vsp = request->vset[i];
	    if (vsp->numval < 0)
		/*
		 * request is malformed, as we cannot control logging
		 * for an undefined instance ... there is no way to
		 * return an error from here, so simply ignore this
		 * metric
		 */
		continue;
	    mflags = find_metric(vsp->pmid);
	    if (mflags < 0) {
		/* only add new metrics if they are ON or MANDATORY OFF
		 * Careful: mandatory+maybe is mandatory+maybe+off
		 */
		if (PMLC_GET_ON(reqstate) ||
		    (PMLC_GET_MAND(reqstate) && !PMLC_GET_MAYBE(reqstate)))
		    add_metric(vsp, &newtp);
	    }
	    else
		/* already a specification for this metric */
		update_metric(vsp, reqstate, mflags, &newtp);
	}

	/* schedule new logging task if new metric(s) specified */
	if (newtask && newtp != NULL) {
	    if (newtp->t_fetch == NULL) {
		/* the new task ended up with no fetch groups, throw it away */
		if (newtp->t_pmidlist != NULL)
		    free(newtp->t_pmidlist);
		free(newtp);
	    }
	    else {
		/* link new task into tasklist */
		newtp->t_next = tasklist;
		tasklist = newtp;

		/* use only the MAND/ADV and ON/OFF bits of reqstate */
		newtp->t_state = PMLC_GET_STATE(reqstate);
		if (PMLC_GET_ON(reqstate)) {
		    newtp->t_delta = tdelta;
		    newtp->t_afid = __pmAFregister(&tdelta, (void *)newtp,
					       log_callback);
		}
		else
		    newtp->t_delta.tv_sec = newtp->t_delta.tv_usec = 0;
		linkback(newtp);
	    }
	}
    }

#ifdef PCP_DEBUG
    if (pmDebug & DBG_TRACE_APPL0)
	dumpit();
#endif

    /* just ignore advisory+maybe---the returned pmResult will have the metrics
     * in their original state indicating that the request could not be
     * satisfied.
     */

    result = request;
    result->timestamp.tv_sec = result->timestamp.tv_usec = 0;	/* for purify */
    /* write the current state of affairs into the result _pmResult */
    for (i = 0; i < request->numpmid; i++) {

	if (control == PM_LOG_MANDATORY || control == PM_LOG_ADVISORY) {
	    char	**names;

	    sts = pmNameAll(request->vset[i]->pmid, &names);
	    if (sts < 0)
		fprintf(stderr, "  metric: %s", pmIDStr(request->vset[i]->pmid));
	    else {
		fprintf(stderr, "  metric: ");
		__pmPrintMetricNames(stderr, sts, names, " or ");
		free(names);
	    }
	}

	if (request->vset[i]->numval <= 0 && !siamised) {
	    result = siamise_request(request);
	    siamised = 1;
	}
	/*
	 * pmids with numval <= 0 in the request have a null vset ptr in the
	 * in the corresponding place in the siamised result.
	 */
	if (result->vset[i] != NULL)
	    vsp = result->vset[i];
	else {
	    /* the result should also contain the history for an all instances
	     * enquire request.  Control requests just get the current indom
	     * since the user of pmlc really wants to see what's being logged
	     * now rather than in the past.
	     */
	    vsp = build_vset(request->vset[i]->pmid, control == PM_LOG_ENQUIRE);
	    result->vset[i] = vsp;
	}
	vsp->valfmt = PM_VAL_INSITU;
	for (j = 0; j < vsp->numval; j++) {
	    rqp = findoptreq(vsp->pmid, vsp->vlist[j].inst);
	    val = 0;
	    if (rqp == NULL) {
		PMLC_SET_STATE(val, 0);
		PMLC_SET_DELTA(val, 0);
	    }
	    else {
		tp = rqp->r_fetch->f_aux;
		PMLC_SET_STATE(val, tp->t_state);
		PMLC_SET_DELTA(val, (tp->t_delta.tv_sec*1000 + tp->t_delta.tv_usec/1000));
	    }

	    val |= gethistflags(vsp->pmid, vsp->vlist[j].inst);
	    vsp->vlist[j].value.lval = val;

	    if (control == PM_LOG_MANDATORY || control == PM_LOG_ADVISORY) {
		int	expstate = 0;
		int	statemask = 0;
		int	expdelta;
		if (rqp != NULL && rqp->r_desc->indom != PM_INDOM_NULL) {
		    char	*p;
		    if (j == 0)
			fputc('\n', stderr);
		    if (pmNameInDom(rqp->r_desc->indom, vsp->vlist[j].inst, &p) >= 0) {
			fprintf(stderr, "    instance: %s", p);
			free(p);
		    }
		    else
			fprintf(stderr, "    instance: #%d", vsp->vlist[j].inst);
		}
		else {
		    /* no pmDesc ... punt */
		    if (vsp->numval > 1 || vsp->vlist[j].inst != PM_IN_NULL) {
			if (j == 0)
			    fputc('\n', stderr);
			fprintf(stderr, "    instance: #%d", vsp->vlist[j].inst);
		    }
		}
		if (state != PM_LOG_MAYBE) {
		    if (control == PM_LOG_MANDATORY)
			PMLC_SET_MAND(expstate, 1);
		    else
			PMLC_SET_MAND(expstate, 0);
		    if (state == PM_LOG_ON)
			PMLC_SET_ON(expstate, 1);
		    else
			PMLC_SET_ON(expstate, 0);
		    PMLC_SET_MAND(statemask, 1);
		    PMLC_SET_ON(statemask, 1);
		}
		else {
		    PMLC_SET_MAND(expstate, 0);
		    PMLC_SET_MAND(statemask, 1);
		}
		expdelta = PMLC_GET_ON(expstate) ? delta : 0;
		if ((PMLC_GET_STATE(val) & statemask) != expstate ||
		    PMLC_GET_DELTA(val) != expdelta)
			fprintf(stderr, " [request failed]");
		fputc('\n', stderr);
	    }
	}
    }

#ifdef PCP_DEBUG
    if (pmDebug & DBG_TRACE_LOG) {
	__pmDumpResult(stderr, result);
    }
#endif

    if ((sts = __pmSendResult(clientfd, FROM_ANON, result)) < 0)
		__pmNotifyErr(LOG_ERR,
			     "do_control: error sending Error PDU to client: %s\n",
			     pmErrStr(sts));

    if (siamised) {
	for (i = 0; i < request->numpmid; i++)
	    if (request->vset[i]->numval <= 0)
		free(result->vset[i]);
	free(result);
    }
    pmFreeResult(request);

    return 0;
}
Exemple #8
0
/*
 * 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;
}
Exemple #9
0
int
main(int argc, char **argv)
{
    int		sts;
    int		c;
    int		help = 0;
    int		oneline = 0;
    char	*pmnsfile = PM_NS_DEFAULT;
    int		errflag = 0;
    int		aflag = 0;
    int		eflag = 0;
    int		allpmid = 0;
    int		allindom = 0;
    char	*filename;
    char	*tp;
    char	*name;
    int		id;
    int		next_type;
    char	*endnum;

    __pmSetProgname(argv[0]);

    while ((c = getopt(argc, argv, "D:eHin:Opv:?")) != EOF) {
	switch (c) {

	case 'D':	/* debug flag */
	    sts = __pmParseDebug(optarg);
	    if (sts < 0) {
		fprintf(stderr, "%s: unrecognized debug flag specification (%s)\n",
		    pmProgname, optarg);
		errflag++;
	    }
	    else
		pmDebug |= sts;
	    break;

	case 'e':	/* help text exists? */
	    eflag = 1;
	    break;

	case 'H':	/* help text */
	    help = 1;
	    break;

	case 'i':
	    aflag++;
	    allindom = 1;
	    break;

	case 'n':	/* alternative namespace file */
	    pmnsfile = optarg;
	    break;

	case 'O':	/* oneline text */
	    oneline = 1;
	    break;

	case 'p':
	    aflag++;
	    allpmid = 1;
	    break;

	case 'v':	/* version 2 only these days */
	    version = (int)strtol(optarg, &endnum, 10);
	    if (*endnum != '\0') {
		fprintf(stderr, "%s: -v requires numeric argument\n", pmProgname);
		errflag++;
	    }
	    if (version != 2) {
		fprintf(stderr 
                       ,"%s: deprecated option - only version 2 is supported\n"
                       , pmProgname);
		errflag++;
	    }
	    break;

	case '?':
	default:
	    errflag++;
	    break;
	}
    }

    if (optind == argc) {
	fprintf(stderr, "%s: missing helpfile argument\n\n", pmProgname);
	errflag = 1;
    }

    if (aflag && optind < argc-1) {
	fprintf(stderr, "%s: metricname arguments cannot be used with -i or -p\n\n",
	    pmProgname);
	errflag = 1;
    }

    if (aflag == 0 && optind == argc-1 && oneline+help != 0) {
	fprintf(stderr, "%s: -O or -H require metricname arguments or -i or -p\n\n",
	    pmProgname);
	errflag = 1;
    }

    if (eflag && (allpmid || allindom)) {
	fprintf(stderr, "%s: -e cannot be used with -i or -p\n\n",
	    pmProgname);
	errflag = 1;
    }

    if (errflag || optind >= argc) {
	fprintf(stderr,
"Usage: %s helpfile\n"
"       %s [options] helpfile [metricname ...]\n"
"\n"
"Options:\n"
"  -e           exists check, only report metrics with no help text\n"
"  -H           display verbose help text\n"
"  -i           process all the instance domains\n"
"  -n pmnsfile  use an alternative PMNS\n"
"  -O           display the one line help summary\n"
"  -p           process all the metrics (PMIDs)\n"
"  -v version   deprecated (only version 2 format supported)\n"
"\n"
"No options implies silently check internal integrity of the helpfile.\n",
		pmProgname, pmProgname);
	exit(1);
    }

    filename = argv[optind++];
    if ((handle = pmdaOpenHelp(filename)) < 0) {
	fprintf(stderr, "pmdaOpenHelp: failed to open \"%s\": ", filename);
	if (handle == -EINVAL)
	    fprintf(stderr, "Bad format, not version %d PCP help text\n", version);
	else
	    fprintf(stderr, "%s\n", pmErrStr(handle));
	exit(1);
    }

    if ((sts = pmLoadASCIINameSpace(pmnsfile, 1)) < 0) {
	fprintf(stderr, "pmLoadASCIINameSpace(%s, 1): %s\n", pmnsfile, pmErrStr(sts));
	exit(1);
    }

    if (help + oneline == 0 && (optind < argc || aflag))
	/* if metric names, -p or -i => -O is default */
	oneline = 1;

    if (optind == argc && aflag == 0)
	/* no metric names, process all entries */
	aflag = 1;

    if (eflag) {
	if (optind == argc) {
	    sts = pmTraversePMNS("", dometric);
	    if (sts < 0) {
		fprintf(stderr, "Error: pmTraversePMNS(\"\", ...): %s\n", pmErrStr(sts));
	    }
	}
	else {
	    for ( ; optind < argc; optind++) {
		sts = pmTraversePMNS(argv[optind], dometric);
		if (sts < 0)
		    fprintf(stderr, "Error: pmTraversePMNS(\"%s\", ...): %s\n", argv[optind], pmErrStr(sts));
	    }
	}
	exit(0);
    }

    while (optind < argc || aflag) {
	if (aflag) {
	    if (next(&id, &next_type) == 0)
		break;
#ifdef PCP_DEBUG
	    if ((pmDebug & DBG_TRACE_APPL0) && allindom+allpmid == 0)
		fprintf(stderr, "next_type=%d id=0x%x\n", next_type, id);
#endif
	    if (next_type == 2) {
		if (!allindom)
		    continue;
		printf("\nInDom %s:", pmInDomStr((pmInDom)id));
	    }
	    else {
		char		**names;
		if (!allpmid)
		    continue;

		printf("\nPMID %s", pmIDStr((pmID)id));
		sts = pmNameAll(id, &names);
		if (sts > 0) {
		    printf(" ");
		    __pmPrintMetricNames(stdout, sts, names, " or ");
		    free(names);
		}
		putchar(':');
	    }
	}
	else {
	    next_type = 1;
	    name = argv[optind++];
	    if ((sts = pmLookupName(1, &name, (pmID *)&id)) < 0) {
		printf("\n%s: %s\n", name, pmErrStr(sts));
		continue;
	    }
	    if (id == PM_ID_NULL) {
		printf("\n%s: unknown metric\n", name);
		continue;
	    }
	    printf("\nPMID %s %s:", pmIDStr((pmID)id), name);
	}

	if (oneline) {
	    if (next_type == 1)
		tp = pmdaGetHelp(handle, (pmID)id, PM_TEXT_ONELINE);
	    else
		tp = pmdaGetInDomHelp(handle, (pmInDom)id, PM_TEXT_ONELINE);
	    if (tp != NULL)
		printf(" %s", tp);
	    putchar('\n');
	}

	if (help) {
	    if (next_type == 1)
		tp = pmdaGetHelp(handle, (pmID)id, PM_TEXT_HELP);
	    else
		tp = pmdaGetInDomHelp(handle, (pmInDom)id, PM_TEXT_HELP);
	    if (tp != NULL && *tp)
		printf("%s\n", tp);
	}

    }

    return 0;
}