void setup_context(void) { int sts; #ifdef PM_MULTI_THREAD pthread_mutex_t save_c_lock; #endif /* * we don't want or need any PMDAs to be loaded for this one * PM_CONTEXT_LOCAL context */ pmSpecLocalPMDA("clear"); if ((sts = pmNewContext(PM_CONTEXT_LOCAL, NULL)) < 0) { fprintf(stderr, "setup_context: creation failed: %s\n", pmErrStr(sts)); exit(1); } ctxp = __pmHandleToPtr(sts); if (ctxp == NULL) { fprintf(stderr, "botch: setup_context: __pmHandleToPtr(%d) returns NULL!\n", sts); exit(1); } /* * Note: This application is single threaded, and once we have ctxp * the associated __pmContext will not move and will only be * accessed or modified synchronously either here or in libpcp. * We unlock the context so that it can be locked as required * within libpcp. */ PM_UNLOCK(ctxp->c_lock); #ifdef PM_MULTI_THREAD /* need to be careful about the initialized lock */ save_c_lock = ctxp->c_lock; #endif memset(ctxp, 0, sizeof(__pmContext)); #ifdef PM_MULTI_THREAD ctxp->c_lock = save_c_lock; #endif ctxp->c_type = PM_CONTEXT_HOST; reset_profile(); }
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 }