示例#1
0
文件: dbpmda.c 项目: ColeJackes/pcp
/*
 * called before regular exit() or as atexit() handler
 */
static void
cleanup()
{
    if (connmode == CONN_DSO)
	closedso();
    else if (connmode == CONN_DAEMON)
	closepmda();
    connmode = NO_CONN;
}
示例#2
0
文件: dso.c 项目: linwukang/pcp
void
opendso(char *dso, char *init, int domain)
{
#ifdef HAVE_DLOPEN
    struct stat		buf;
    unsigned int	challenge;

    dispatch.status = -1;

    if (stat(dso, &buf) < 0) {
        fprintf(stderr, "opendso: %s: %s\n", dso, osstrerror());
        return;
    }

    closedso();
    /*
     * RTLD_NOW would be better in terms of detecting unresolved symbols
     * now, rather than taking a SEGV later ... but various combinations
     * of dynamic and static libraries used to create the DSO PMDA,
     * combined with hiding symbols in the DSO PMDA may result in benign
     * unresolved symbols remaining and the dlopen() would fail under
     * these circumstances.
     */
    handle = dlopen(dso, RTLD_LAZY);
    if (handle == NULL) {
        printf("Error attaching DSO \"%s\"\n", dso);
        printf("%s\n\n", dlerror());
    }
    else {
        void	(*initp)(pmdaInterface *);
        initp = (void (*)(pmdaInterface *))dlsym(handle, init);
        if (initp == NULL) {
            printf("Error: couldn't find init function \"%s\" in DSO \"%s\"\n",
                   init, dso);
            dlclose(handle);
        }
        else {
            /*
             * the PMDA interface / PMAPI version discovery as a "challenge" ...
             * for pmda_interface it is all the bits being set,
             * for pmapi_version it is the complement of the one you are
             * using now
             */
            challenge = 0xff;
            dispatch.comm.pmda_interface = challenge;
            dispatch.comm.pmapi_version = ~PMAPI_VERSION;
            dispatch.comm.flags = 0;
            dispatch.status = 0;
#ifdef PCP_DEBUG
            if (pmDebug & DBG_TRACE_PDU)
                fprintf(stderr, "DSO init %s->"PRINTF_P_PFX"%p() domain=%d challenge: pmda_interface=0x%x pmapi_version=%d\n",
                        init, initp, dispatch.domain,
                        dispatch.comm.pmda_interface,
                        (~dispatch.comm.pmapi_version) & 0xff);
#endif
            dispatch.domain = domain;

            (*initp)(&dispatch);

            if (dispatch.status != 0) {
                printf("Error: initialization routine \"%s\" failed in DSO \"%s\": %s\n",
                       init, dso, pmErrStr(dispatch.status));
                dispatch.status = -1;
                dlclose(handle);
            }
            else {
                if (dispatch.comm.pmda_interface < PMDA_INTERFACE_2 ||
                        dispatch.comm.pmda_interface > PMDA_INTERFACE_LATEST) {

                    printf("Error: Unsupported PMDA interface version %d returned by DSO \"%s\"\n",
                           dispatch.comm.pmda_interface, dso);
                    dispatch.status = -1;
                    dlclose(handle);
                }
                if (dispatch.comm.pmapi_version != PMAPI_VERSION_2) {
                    printf("Error: Unsupported PMAPI version %d returned by DSO \"%s\"\n",
                           dispatch.comm.pmapi_version, dso);
                    dispatch.status = -1;
                    dlclose(handle);
                }
            }

            if (dispatch.status == 0) {
#ifdef PCP_DEBUG
                if (pmDebug & DBG_TRACE_PDU) {
                    fprintf(stderr, "DSO has domain=%d", dispatch.domain);
                    fprintf(stderr, " pmda_interface=%d pmapi_version=%d\n",
                            dispatch.comm.pmda_interface,
                            dispatch.comm.pmapi_version);
                }
#endif
                dsoname = strdup(dso);
                connmode = CONN_DSO;
                reset_profile();

                if (myPmdaName != NULL)
                    free(myPmdaName);
                myPmdaName = strdup(dso);

                /*
                 * set here once and used by all subsequent calls into the
                 * PMDA
                 */
                if (dispatch.comm.pmda_interface >= PMDA_INTERFACE_5)
                    dispatch.version.four.ext->e_context = 0;
            }
        }
    }
#else /* ! HAVE_DLOPEN */
    dispatch.status = -1;

    fprintf(stderr, "opendso: %s: No dynamic DSO/DLL support on this platform\n", dso);
#endif
}
示例#3
0
文件: dbpmda.c 项目: ColeJackes/pcp
int
main(int argc, char **argv)
{
    int			c;
    int			sts;
    char		*endnum;

    iflag = isatty(0);

    while ((c = pmgetopt_r(argc, argv, &opts)) != EOF) {
	switch (c) {

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

	case 'e':		/* echo input */
	    eflag++;
	    break;

	case 'f':		/* skip .dbpmdarc processing */
	    fflag++;
	    break;

	case 'i':		/* be interactive */
	    iflag = 1;
	    break;

	case 'n':		/* alternative name space file */
	    pmnsfile = opts.optarg;
	    break;

	case 'q':
	    sts = (int)strtol(opts.optarg, &endnum, 10);
	    if (*endnum != '\0' || sts <= 0.0) {
		pmprintf("%s: -q requires a positive numeric argument\n",
			pmProgname);
		opts.errors++;
	    } else {
		_creds_timeout = sts;
	    }
	    break;

	case 'U':		/* run under alternate user account */
	    __pmSetProcessIdentity(opts.optarg);
	    break;

	default:
	case '?':
	    opts.errors++;
	    break;
	}
    }

    if ((c = argc - opts.optind) > 0) {
	if (c > 1)
	    opts.errors++;
	else {
	    /* pid was specified */
	    if (primary) {
		pmprintf("%s: you may not specify both -P and a pid\n",
			pmProgname);
		opts.errors++;
	    }
	    else {
		pid = (int)strtol(argv[opts.optind], &endnum, 10);
		if (*endnum != '\0') {
		    pmprintf("%s: pid must be a numeric process id\n",
			    pmProgname);
		    opts.errors++;
		}
	    }
	}
    }

    if (opts.errors) {
	pmUsageMessage(&opts);
	exit(1);
    }

    if (pmnsfile == PM_NS_DEFAULT) {
	if ((sts = pmLoadNameSpace(pmnsfile)) < 0) {
		fprintf(stderr, "%s: Cannot load default namespace: %s\n",
			pmProgname, pmErrStr(sts));
	    exit(1);
	}
    }
    else {
	if ((sts = pmLoadASCIINameSpace(pmnsfile, 1)) < 0) {
		fprintf(stderr, "%s: Cannot load namespace from \"%s\": %s\n",
			pmProgname, pmnsfile, pmErrStr(sts));
	    exit(1);
	}
    }

    /* initialize the "fake context" ... */
    setup_context();

    setlinebuf(stdout);
    setlinebuf(stderr);

#ifdef HAVE_ATEXIT
    atexit(cleanup);
#endif

    for ( ; ; ) {
	initmetriclist();
	yyparse();
	if (yywrap()) {
	    if (iflag)
		putchar('\n');
	    break;
	}

	__pmSetInternalState(PM_STATE_PMCS);

	switch (stmt_type) {

	    case OPEN:
		profile_changed = 1;
		break;

	    case CLOSE:
		switch (connmode) {
		    case CONN_DSO:
			closedso();
			break;
		    
		    case CONN_DAEMON:
			closepmda();
			break;
		    
		    case NO_CONN:
			yywarn("No PMDA currently opened");
			break;
		}
		connmode = NO_CONN;
		break;

	    case DESC:
		switch (connmode) {
		    case CONN_DSO:
			dodso(PDU_DESC_REQ);
			break;
		    
		    case CONN_DAEMON:
			dopmda(PDU_DESC_REQ);
			break;
		    
		    case NO_CONN:
			yywarn("No PMDA currently opened");
			break;
		}
		break;

	    case FETCH:
		switch (connmode) {
		    case CONN_DSO:
			dodso(PDU_FETCH);
			break;
		    
		    case CONN_DAEMON:
			dopmda(PDU_FETCH);
			break;
		    
		    case NO_CONN:
			yywarn("No PMDA currently opened");
			break;
		}
		break;

	    case INSTANCE:
		switch (connmode) {
		    case CONN_DSO:
			dodso(PDU_INSTANCE_REQ);
			break;
		    
		    case CONN_DAEMON:
			dopmda(PDU_INSTANCE_REQ);
			break;
		    
		    case NO_CONN:
			yywarn("No PMDA currently opened");
			break;
		}
		break;

	    case STORE:
		switch (connmode) {
		    case CONN_DSO:
			dodso(PDU_RESULT);
			break;
		    
		    case CONN_DAEMON:
			dopmda(PDU_RESULT);
			break;
		    
		    case NO_CONN:
			yywarn("No PMDA currently opened");
			break;
		}
		break;

	    case HELP:
		dohelp(param.number, param.pmid);
		break;

	    case WATCH:
		break;

	    case DBG:
		pmDebug = param.number;
		break;

	    case QUIT:
		goto done;

	    case STATUS:
		dostatus();
		break;

	    case INFO:
		switch (connmode) {
		case CONN_DSO:
		    dodso(PDU_TEXT_REQ);
		    break;

		case CONN_DAEMON:
		    dopmda(PDU_TEXT_REQ);
		    break;

		case NO_CONN:
		    yywarn("No PMDA currently opened");
		    break;
		}
		break;
	    case NAMESPACE:
		if (cmd_namespace != NULL)
		    free(cmd_namespace);
		cmd_namespace = strdup(param.name);
		if (cmd_namespace == NULL) {
		    fprintf(stderr, "%s: No memory for new namespace\n",
			    pmProgname);
		    exit(1);
		}
		pmUnloadNameSpace();
		strcpy(cmd_namespace, param.name);
		if ((sts = pmLoadASCIINameSpace(cmd_namespace, 1)) < 0) {
		    fprintf(stderr, "%s: Cannot load namespace from \"%s\": %s\n",
			    pmProgname, cmd_namespace, pmErrStr(sts));

		    pmUnloadNameSpace();
		    if (pmnsfile == PM_NS_DEFAULT) {
			fprintf(stderr, "%s: Reload default namespace\n",
				pmProgname);
			if ((sts = pmLoadNameSpace(pmnsfile)) < 0) {
			    fprintf(stderr,
				    "%s: Cannot load default namespace: %s\n",
				    pmProgname, pmErrStr(sts));
			    exit(1);
			}
		    }
		    else {
			fprintf(stderr, "%s: Reload namespace from \"%s\"\n",
				pmProgname, pmnsfile);
			if ((sts = pmLoadASCIINameSpace(pmnsfile, 1)) < 0) {
			    fprintf(stderr,
				    "%s: Cannot load namespace from \"%s\""
				    ": %s\n",
				    pmProgname, pmnsfile, pmErrStr(sts));
			    exit(1);
			}
		    }
		}
		break;

	    case EOL:
		break;

	    case PMNS_NAME:
		switch (connmode) {
		    case CONN_DSO:
			dodso(PDU_PMNS_IDS);
			break;
		    
		    case CONN_DAEMON:
			dopmda(PDU_PMNS_IDS);
			break;
		    
		    case NO_CONN:
			yywarn("No PMDA currently opened");
			break;
		}
		break;

	    case PMNS_PMID:
		switch (connmode) {
		    case CONN_DSO:
			dodso(PDU_PMNS_NAMES);
			break;
		    
		    case CONN_DAEMON:
			dopmda(PDU_PMNS_NAMES);
			break;
		    
		    case NO_CONN:
			yywarn("No PMDA currently opened");
			break;
		}
		break;

	    case PMNS_CHILDREN:
		switch (connmode) {
		    case CONN_DSO:
			dodso(PDU_PMNS_CHILD);
			break;
		    
		    case CONN_DAEMON:
			dopmda(PDU_PMNS_CHILD);
			break;
		    
		    case NO_CONN:
			yywarn("No PMDA currently opened");
			break;
		}
		break;

	    case PMNS_TRAVERSE:
		switch (connmode) {
		    case CONN_DSO:
			dodso(PDU_PMNS_TRAVERSE);
			break;
		    
		    case CONN_DAEMON:
			dopmda(PDU_PMNS_TRAVERSE);
			break;
		    
		    case NO_CONN:
			yywarn("No PMDA currently opened");
			break;
		}
		break;

	    case ATTR:
		switch (connmode) {
		    case CONN_DSO:
			dodso(PDU_AUTH);
			break;
		    
		    case CONN_DAEMON:
			dopmda(PDU_AUTH);
			break;
		    
		    case NO_CONN:
			yywarn("No PMDA currently opened");
			break;
		}
		break;

	    default:
		printf("Unexpected result (%d) from parser?\n", stmt_type);
		break;
	}
	__pmSetInternalState(PM_STATE_APPL);
    }

done:
    cleanup();

    exit(0);
}