void __pmConfig(__pmConfigCallback formatter) { /* * Scan ${PCP_CONF-$PCP_DIR/etc/pcp.conf} and put all PCP config * variables found therein into the environment. */ FILE *fp; char confpath[32]; char dir[MAXPATHLEN]; char var[MAXPATHLEN]; char *prefix; char *conf; char *val; char *p; PM_INIT_LOCKS(); PM_LOCK(__pmLock_libpcp); prefix = getenv("PCP_DIR"); if ((conf = getenv("PCP_CONF")) == NULL) { strncpy(confpath, "/etc/pcp.conf", sizeof(confpath)); if (prefix == NULL) conf = __pmNativePath(confpath); else { snprintf(dir, sizeof(dir), "%s%s", prefix, __pmNativePath(confpath)); conf = dir; } } if (access((const char *)conf, R_OK) < 0 || (fp = fopen(conf, "r")) == (FILE *)NULL) { char errmsg[PM_MAXERRMSGLEN]; pmprintf("FATAL PCP ERROR: could not open config file \"%s\" : %s\n", conf, osstrerror_r(errmsg, sizeof(errmsg))); pmprintf("You may need to set PCP_CONF or PCP_DIR in your environment.\n"); pmflush(); PM_UNLOCK(__pmLock_libpcp); exit(1); } while (fgets(var, sizeof(var), fp) != NULL) { if (var[0] == '#' || (p = strchr(var, '=')) == NULL) continue; *p = '\0'; val = p+1; if ((p = strrchr(val, '\n')) != NULL) *p = '\0'; if ((p = getenv(var)) != NULL) val = p; else formatter(var, prefix, val); if (pmDebug & DBG_TRACE_CONFIG) fprintf(stderr, "pmGetConfig: (init) %s=%s\n", var, val); } fclose(fp); PM_UNLOCK(__pmLock_libpcp); }
int __pmUnpinPDUBuf(void *handle) { bufctl_t *pcp, pcp_search; void *bcp; assert(((__psint_t)handle % sizeof(int)) == 0); PM_INIT_LOCKS(); PM_LOCK(__pmLock_libpcp); /* * Initialize a dummy bufctl_t to use only as search key; * only its bc_buf & bc_size fields need to be set, as that's * all that bufctl_t_compare will look at. */ pcp_search.bc_buf = handle; pcp_search.bc_size = 1; bcp = tfind(&pcp_search, &buf_tree, &bufctl_t_compare); /* * NB: don't release the lock until final disposition of this object; * we don't want to play TOCTOU. */ if (likely(bcp != NULL)) { pcp = *(bufctl_t **)bcp; } else { #ifdef PCP_DEBUG if (pmDebug & DBG_TRACE_PDUBUF) { fprintf(stderr, "__pmUnpinPDUBuf(" PRINTF_P_PFX "%p) -> fails\n", handle); pdubufdump(); } #endif PM_UNLOCK(__pmLock_libpcp); return 0; } #ifdef PCP_DEBUG if (unlikely(pmDebug & DBG_TRACE_PDUBUF)) fprintf(stderr, "__pmUnpinPDUBuf(" PRINTF_P_PFX "%p) -> pdubuf=" PRINTF_P_PFX "%p, pincnt=%d\n", handle, pcp->bc_buf, pcp->bc_pincnt - 1); #endif assert((&pcp->bc_buf[0] <= (char*)handle) && ((char*)handle < &pcp->bc_buf[pcp->bc_size])); if (likely(--pcp->bc_pincnt == 0)) { tdelete(pcp, &buf_tree, &bufctl_t_compare); PM_UNLOCK(__pmLock_libpcp); free(pcp); } else { PM_UNLOCK(__pmLock_libpcp); } return 1; }
static void AFsetup(void) { PM_LOCK(__pmLock_libpcp); if (afsetup) { PM_UNLOCK(__pmLock_libpcp); return; } afsetup = 1; afblock = CreateMutex(NULL, FALSE, NULL); aftimer = CreateWaitableTimer(NULL, TRUE, NULL); PM_UNLOCK(__pmLock_libpcp); }
int __pmPtrToHandle(__pmContext *ctxp) { int i; PM_INIT_LOCKS(); PM_LOCK(__pmLock_libpcp); for (i = 0; i < contexts_len; i++) { if (ctxp == contexts[i]) { PM_UNLOCK(__pmLock_libpcp); return i; } } PM_UNLOCK(__pmLock_libpcp); return PM_CONTEXT_UNDEF; }
int reconnect(void) { int sts; int ctx; __pmContext *ctxp; if ((ctx = pmWhichContext()) >= 0) ctxp = __pmHandleToPtr(ctx); if (ctx < 0 || ctxp == NULL) { fprintf(stderr, "%s: reconnect botch: cannot get context: %s\n", pmProgname, pmErrStr(ctx)); exit(1); } sts = pmReconnectContext(ctx); if (sts >= 0) { time_t now; time(&now); fprintf(stderr, "%s: re-established connection to PMCD on \"%s\" at %s\n", pmProgname, pmcd_host, ctime(&now)); pmcdfd = ctxp->c_pmcd->pc_fd; __pmFD_SET(pmcdfd, &fds); numfds = maxfd() + 1; } PM_UNLOCK(ctxp->c_lock); return sts; }
void disconnect(int sts) { time_t now; #if CAN_RECONNECT int ctx; __pmContext *ctxp; #endif time(&now); if (sts != 0) fprintf(stderr, "%s: Error: %s\n", pmProgname, pmErrStr(sts)); fprintf(stderr, "%s: Lost connection to PMCD on \"%s\" at %s", pmProgname, pmcd_host, ctime(&now)); #if CAN_RECONNECT if (primary) { fprintf(stderr, "This is fatal for the primary logger."); exit(1); } close(pmcdfd); __pmFD_CLR(pmcdfd, &fds); pmcdfd = -1; numfds = maxfd() + 1; if ((ctx = pmWhichContext()) >= 0) ctxp = __pmHandleToPtr(ctx); if (ctx < 0 || ctxp == NULL) { fprintf(stderr, "%s: disconnect botch: cannot get context: %s\n", pmProgname, pmErrStr(ctx)); exit(1); } ctxp->c_pmcd->pc_fd = -1; PM_UNLOCK(ctxp->c_lock); #else exit(1); #endif }
static void posix_formatter(char *var, char *prefix, char *val) { /* +40 bytes for max PCP env variable name */ char envbuf[MAXPATHLEN+40]; char *vp; char *vend; snprintf(envbuf, sizeof(envbuf), "%s=", var); vend = &val[strlen(val)-1]; if (val[0] == *vend && (val[0] == '\'' || val[0] == '"')) { /* * have quoted value like "gawk --posix" for $PCP_AWK_PROG ... * strip quotes */ vp = &val[1]; vend--; } else vp = val; strncat(envbuf, vp, vend-vp+1); envbuf[strlen(var)+1+vend-vp+1+1] = '\0'; PM_LOCK(__pmLock_libpcp); putenv(strdup(envbuf)); PM_UNLOCK(__pmLock_libpcp); (void)prefix; }
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; }
int pmFetchArchive(pmResult **result) { int n; __pmContext *ctxp; int ctxp_mode; if ((n = pmWhichContext()) >= 0) { ctxp = __pmHandleToPtr(n); if (ctxp == NULL) n = PM_ERR_NOCONTEXT; else { ctxp_mode = (ctxp->c_mode & __PM_MODE_MASK); if (ctxp->c_type != PM_CONTEXT_ARCHIVE) n = PM_ERR_NOTARCHIVE; else if (ctxp_mode == PM_MODE_INTERP) /* makes no sense! */ n = PM_ERR_MODE; else { /* assume PM_CONTEXT_ARCHIVE and BACK or FORW */ n = __pmLogFetch(ctxp, 0, NULL, result); if (n >= 0) { ctxp->c_origin.tv_sec = (__int32_t)(*result)->timestamp.tv_sec; ctxp->c_origin.tv_usec = (__int32_t)(*result)->timestamp.tv_usec; } } PM_UNLOCK(ctxp->c_lock); } } return n; }
const struct timeval * __pmDefaultRequestTimeout(void) { static int done_default = 0; PM_INIT_LOCKS(); PM_LOCK(__pmLock_libpcp); if (!done_default) { char *timeout_str; char *end_ptr; if ((timeout_str = getenv("PMCD_REQUEST_TIMEOUT")) != NULL) { def_timeout = strtod(timeout_str, &end_ptr); if (*end_ptr != '\0' || def_timeout < 0.0) { __pmNotifyErr(LOG_WARNING, "ignored bad PMCD_REQUEST_TIMEOUT = '%s'\n", timeout_str); } else { __pmtimevalFromReal(def_timeout, &def_wait); } } done_default = 1; } PM_UNLOCK(__pmLock_libpcp); return (&def_wait); }
int main(int argc, char **argv) { char *p; struct timeval delta = { 1, 0 }; if (argc != 2) _usage(); __pmAFregister(&delta, NULL, timeout); #ifdef DBG_TRACE_DESPERATE pmDebug |= DBG_TRACE_DESPERATE; #endif for (p = argv[1]; *p; p++) { switch (*p) { case 'i': fprintf(stderr, "initialize\n"); PM_INIT_LOCKS(); break; case 'l': fprintf(stderr, "lock\n"); PM_LOCK(__pmLock_libpcp); break; case 'u': fprintf(stderr, "unlock\n"); PM_UNLOCK(__pmLock_libpcp); break; default: _usage(); } } return 0; }
int __pmSecureServerCertificateSetup(const char *db, const char *passwd, const char *cert_nickname) { PM_INIT_LOCKS(); PM_LOCK(secureserver_lock); /* Configure optional (cmdline) password file in case DB locked */ secure_server.password_file = passwd; /* * Configure location of the NSS database with a sane default. * For servers, we default to the shared (sql) system-wide database. * If command line db specified, pass it directly through - allowing * any old database format, at the users discretion. */ if (db) { /* shortened-buffer-size (-2) guarantees null-termination */ strncpy(secure_server.database_path, db, MAXPATHLEN-2); } if (cert_nickname) { strncpy(secure_server.cert_nickname, cert_nickname, MAX_CERT_NAME_LENGTH-2); } else { strncpy(secure_server.cert_nickname, SECURE_SERVER_CERTIFICATE, MAX_CERT_NAME_LENGTH-2); } PM_UNLOCK(secureserver_lock); return 0; }
void disconnect(int sts) { time_t now; int ctx; __pmContext *ctxp; time(&now); if (sts != 0) fprintf(stderr, "%s: Error: %s\n", pmProgname, pmErrStr(sts)); fprintf(stderr, "%s: Lost connection to PMCD on \"%s\" at %s", pmProgname, pmcd_host, ctime(&now)); if (pmcdfd != -1) { close(pmcdfd); __pmFD_CLR(pmcdfd, &fds); pmcdfd = -1; } numfds = maxfd() + 1; if ((ctx = pmWhichContext()) >= 0) ctxp = __pmHandleToPtr(ctx); if (ctx < 0 || ctxp == NULL) { fprintf(stderr, "%s: disconnect botch: cannot get context: %s\n", pmProgname, pmErrStr(ctx)); exit(1); } ctxp->c_pmcd->pc_fd = -1; PM_UNLOCK(ctxp->c_lock); }
__pmPDU * __pmFindPDUBuf(int need) { bufctl_t *pcp; void *bcp; PM_INIT_LOCKS(); if (unlikely(need < 0)) { /* special diagnostic case ... dump buffer state */ #ifdef PCP_DEBUG fprintf(stderr, "__pmFindPDUBuf(DEBUG)\n"); pdubufdump(); #endif return NULL; } if ((pcp = (bufctl_t *)malloc(sizeof(*pcp) + need)) == NULL) { return NULL; } pcp->bc_pincnt = 1; pcp->bc_size = need; pcp->bc_buf = ((char *)pcp) + sizeof(*pcp); PM_LOCK(__pmLock_libpcp); /* Insert the node in the tree. */ bcp = tsearch((void *)pcp, &buf_tree, &bufctl_t_compare); if (unlikely(bcp == NULL)) { /* ENOMEM */ PM_UNLOCK(__pmLock_libpcp); free(pcp); return NULL; } PM_UNLOCK(__pmLock_libpcp); #ifdef PCP_DEBUG if (unlikely(pmDebug & DBG_TRACE_PDUBUF)) { fprintf(stderr, "__pmFindPDUBuf(%d) -> " PRINTF_P_PFX "%p\n", need, pcp->bc_buf); pdubufdump(); } #endif return (__pmPDU *)pcp->bc_buf; }
/* * On success, context is locked and caller should unlock it */ __pmContext * __pmHandleToPtr(int handle) { PM_INIT_LOCKS(); PM_LOCK(__pmLock_libpcp); if (handle < 0 || handle >= contexts_len || contexts[handle]->c_type == PM_CONTEXT_FREE) { PM_UNLOCK(__pmLock_libpcp); return NULL; } else { __pmContext *sts; sts = contexts[handle]; PM_UNLOCK(__pmLock_libpcp); PM_LOCK(sts->c_lock); return sts; } }
long pm_set_mclk_source(pm_clk_src_t src) { AVR32_ENTER_CRITICAL_REGION( ); // Unlock the write-protected MCCTRL register PM_UNLOCK(AVR32_PM_MCCTRL); AVR32_PM.mcctrl = src; AVR32_LEAVE_CRITICAL_REGION( ); return PASS; }
/* * For native Win32 console tools, we need to translate the paths * used in scripts to native paths with PCP_DIR prefix prepended. * * For Win32 MSYS shell usage, we need to translate the paths * used in scripts to paths with PCP_DIR prefix prepended AND * drive letter path mapping done AND posix-style separators. * * Choose which way to go based on our environment (SHELL). */ static int posix_style(void) { char *s; int sts; PM_LOCK(__pmLock_libpcp); s = getenv("SHELL"); sts = (s && strncmp(s, "/bin/", 5) == 0); PM_UNLOCK(__pmLock_libpcp); return sts; }
static char * pmgetconfig(const char *name, int fatal) { /* * state controls one-trip initialization, and recursion guard * for pathological failures in initialization */ static int state = 0; char *val; PM_INIT_LOCKS(); PM_LOCK(__pmLock_libpcp); if (state == 0) { state = 1; PM_UNLOCK(__pmLock_libpcp); __pmconfig(__pmNativeConfig, fatal); PM_LOCK(__pmLock_libpcp); state = 2; } else if (state == 1) { /* recursion from error in __pmConfig() ... no value is possible */ PM_UNLOCK(__pmLock_libpcp); if (pmDebug & DBG_TRACE_CONFIG) fprintf(stderr, "pmgetconfig: %s= ... recursion error\n", name); if (!fatal) return NULL; val = ""; return val; } PM_UNLOCK(__pmLock_libpcp); if ((val = getenv(name)) == NULL) { if (!fatal) return NULL; val = ""; } if (pmDebug & DBG_TRACE_CONFIG) fprintf(stderr, "pmgetconfig: %s=%s\n", name, val); return val; }
int reconnect(void) { int sts; int ctx; time_t now; __pmContext *ctxp; if ((ctx = pmWhichContext()) >= 0) ctxp = __pmHandleToPtr(ctx); if (ctx < 0 || ctxp == NULL) { fprintf(stderr, "%s: reconnect botch: cannot get context: %s\n", pmProgname, pmErrStr(ctx)); exit(1); } sts = pmReconnectContext(ctx); if (sts >= 0) { pmcdfd = ctxp->c_pmcd->pc_fd; __pmFD_SET(pmcdfd, &fds); numfds = maxfd() + 1; } PM_UNLOCK(ctxp->c_lock); if (sts < 0) return sts; time(&now); fprintf(stderr, "%s: re-established connection to PMCD on \"%s\" at %s", pmProgname, pmcd_host, ctime(&now)); /* * Metrics may have changed while PMCD was unreachable, so we * need to recheck each metric to make sure that its PMID and * semantics have not changed. We cannot recover if there is * an incompatible change - must defer to controlling scripts * or processes (a new-named archive will have to be created, * from a new pmlogger process, and pmlogrewrite/pmlogextract * will need to become involved if they need to be merged). */ validate_metrics(); /* * All metrics have been validated, however, this state change * represents a potential gap in the stream of metrics. So we * must store a <mark> record at this point. */ if ((sts = putmark()) < 0) { fprintf(stderr, "putmark: %s\n", pmErrStr(sts)); exit(1); } return 0; }
static int __pmSecureServerNegotiation(int fd, int *strength) { PRIntervalTime timer; PRFileDesc *sslsocket; SECStatus secsts; int enabled, keysize; int msec; sslsocket = (PRFileDesc *)__pmGetSecureSocket(fd); if (!sslsocket) return PM_ERR_IPC; PM_INIT_LOCKS(); PM_LOCK(secureserver_lock); secsts = SSL_ConfigSecureServer(sslsocket, secure_server.certificate, secure_server.private_key, secure_server.certificate_KEA); PM_UNLOCK(secureserver_lock); if (secsts != SECSuccess) { pmNotifyErr(LOG_ERR, "Unable to configure secure server: %s", pmErrStr(__pmSecureSocketsError(PR_GetError()))); return PM_ERR_IPC; } secsts = SSL_ResetHandshake(sslsocket, PR_TRUE /*server*/); if (secsts != SECSuccess) { pmNotifyErr(LOG_ERR, "Unable to reset secure handshake: %s", pmErrStr(__pmSecureSocketsError(PR_GetError()))); return PM_ERR_IPC; } /* Server initiates handshake now to get early visibility of errors */ msec = __pmConvertTimeout(TIMEOUT_DEFAULT); timer = PR_MillisecondsToInterval(msec); secsts = SSL_ForceHandshakeWithTimeout(sslsocket, timer); if (secsts != SECSuccess) { pmNotifyErr(LOG_ERR, "Unable to force secure handshake: %s", pmErrStr(__pmSecureSocketsError(PR_GetError()))); return PM_ERR_IPC; } secsts = SSL_SecurityStatus(sslsocket, &enabled, NULL, &keysize, NULL, NULL, NULL); if (secsts != SECSuccess) return __pmSecureSocketsError(PR_GetError()); *strength = (enabled > 0) ? keysize : DEFAULT_SECURITY_STRENGTH; return 0; }
int pmSetMode(int mode, const struct timeval *when, int delta) { int n; __pmContext *ctxp; int l_mode = (mode & __PM_MODE_MASK); if ((n = pmWhichContext()) >= 0) { ctxp = __pmHandleToPtr(n); if (ctxp == NULL) return PM_ERR_NOCONTEXT; if (ctxp->c_type == PM_CONTEXT_HOST) { if (l_mode != PM_MODE_LIVE) n = PM_ERR_MODE; else { ctxp->c_origin.tv_sec = ctxp->c_origin.tv_usec = 0; ctxp->c_mode = mode; ctxp->c_delta = delta; n = 0; } } else if (ctxp->c_type == PM_CONTEXT_LOCAL) { n = PM_ERR_MODE; } else { /* assume PM_CONTEXT_ARCHIVE */ if (l_mode == PM_MODE_INTERP || l_mode == PM_MODE_FORW || l_mode == PM_MODE_BACK) { if (when != NULL) { /* * special case of NULL for timestamp * => do not update notion of "current" time */ ctxp->c_origin.tv_sec = (__int32_t)when->tv_sec; ctxp->c_origin.tv_usec = (__int32_t)when->tv_usec; } ctxp->c_mode = mode; ctxp->c_delta = delta; __pmLogSetTime(ctxp); __pmLogResetInterp(ctxp); n = 0; } else n = PM_ERR_MODE; } PM_UNLOCK(ctxp->c_lock); } return n; }
void __pmConnectGetPorts(pmHostSpec *host) { PM_INIT_LOCKS(); PM_LOCK(__pmLock_libpcp); load_pmcd_ports(); if (__pmAddHostPorts(host, global_portlist, global_nports) < 0) { __pmNotifyErr(LOG_WARNING, "__pmConnectGetPorts: portlist dup failed, " "using default PMCD_PORT (%d)\n", SERVER_PORT); host->ports[0] = SERVER_PORT; host->nports = 1; } PM_UNLOCK(__pmLock_libpcp); }
void __pmCountPDUBuf(int need, int *alloc, int *free) { PM_INIT_LOCKS(); PM_LOCK(__pmLock_libpcp); pdu_bufcnt_need = need; pdu_bufcnt = 0; twalk(buf_tree, &pdubufcount); *alloc = pdu_bufcnt; *free = 0; /* We don't retain freed nodes. */ PM_UNLOCK(__pmLock_libpcp); }
static void pdubufdump(void) { /* * There is no longer a pdubuf free list, ergo no * fprintf(stderr, " free pdubuf[size]:\n"); */ PM_LOCK(__pmLock_libpcp); if (buf_tree != NULL) { fprintf(stderr, " pinned pdubuf[size](pincnt):"); twalk(buf_tree, &pdubufdump1); fprintf(stderr, "\n"); } PM_UNLOCK(__pmLock_libpcp); }
static void waitawhile(__pmPMCDCtl *ctl) { /* * after failure, compute delay before trying again ... */ PM_LOCK(__pmLock_libpcp); if (n_backoff == 0) { char *q; /* first time ... try for PMCD_RECONNECT_TIMEOUT from env */ if ((q = getenv("PMCD_RECONNECT_TIMEOUT")) != NULL) { char *pend; char *p; int val; for (p = q; *p != '\0'; ) { val = (int)strtol(p, &pend, 10); if (val <= 0 || (*pend != ',' && *pend != '\0')) { __pmNotifyErr(LOG_WARNING, "pmReconnectContext: ignored bad PMCD_RECONNECT_TIMEOUT = '%s'\n", q); n_backoff = 0; if (backoff != NULL) free(backoff); break; } if ((backoff = (int *)realloc(backoff, (n_backoff+1) * sizeof(backoff[0]))) == NULL) { __pmNoMem("pmReconnectContext", (n_backoff+1) * sizeof(backoff[0]), PM_FATAL_ERR); } backoff[n_backoff++] = val; if (*pend == '\0') break; p = &pend[1]; } } if (n_backoff == 0) { /* use default */ n_backoff = 5; backoff = def_backoff; } } PM_UNLOCK(__pmLock_libpcp); if (ctl->pc_timeout == 0) ctl->pc_timeout = 1; else if (ctl->pc_timeout < n_backoff) ctl->pc_timeout++; ctl->pc_again = time(NULL) + backoff[ctl->pc_timeout-1]; }
static void dos_formatter(char *var, char *prefix, char *val) { char envbuf[MAXPATHLEN]; int msys = posix_style(); if (prefix && dos_rewrite_path(var, val, msys)) { char *p = msys ? msys_native_path(prefix) : prefix; snprintf(envbuf, sizeof(envbuf), "%s=%s%s", var, p, val); } else { snprintf(envbuf, sizeof(envbuf), "%s=%s", var, val); } PM_LOCK(__pmLock_libpcp); putenv(strdup(envbuf)); PM_UNLOCK(__pmLock_libpcp); }
static node_t * newnode(int type) { node_t *np; np = (node_t *)malloc(sizeof(node_t)); if (np == NULL) { PM_UNLOCK(registered.mutex); __pmNoMem("pmRegisterDerived: newnode", sizeof(node_t), PM_FATAL_ERR); /*NOTREACHED*/ } np->type = type; np->save_last = 0; np->left = NULL; np->right = NULL; np->value = NULL; np->info = NULL; return np; }
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(); }
static void destroylock(pthread_mutex_t *lock, char *which) { int psts; char errmsg[PM_MAXERRMSGLEN]; if ((psts = pthread_mutex_destroy(lock)) != 0) { pmErrStr_r(-psts, errmsg, sizeof(errmsg)); fprintf(stderr, "pmDestroyContext: pthread_mutex_destroy(%s) failed: %s\n", which, errmsg); /* * Most likely cause is the mutex still being locked ... this is a * a library bug, but potentially recoverable ... */ while (PM_UNLOCK(lock) >= 0) { fprintf(stderr, "pmDestroyContext: extra %s unlock?\n", which); } if ((psts = pthread_mutex_destroy(lock)) != 0) { pmErrStr_r(-psts, errmsg, sizeof(errmsg)); fprintf(stderr, "pmDestroyContext: pthread_mutex_destroy(%s) failed second try: %s\n", which, errmsg); } } }
void __pmSecureServerShutdown(void) { PM_INIT_LOCKS(); PM_LOCK(secureserver_lock); if (secure_server.certificate) { CERT_DestroyCertificate(secure_server.certificate); secure_server.certificate = NULL; } if (secure_server.private_key) { SECKEY_DestroyPrivateKey(secure_server.private_key); secure_server.private_key = NULL; } if (secure_server.ssl_session_cache_setup) { SSL_ShutdownServerSessionIDCache(); secure_server.ssl_session_cache_setup = 0; } if (secure_server.initialized) { NSS_Shutdown(); secure_server.initialized = 0; } PM_UNLOCK(secureserver_lock); }