/* use documented in pmdaAttribute(3) */ static int papi_contextAttributeCallBack(int context, int attr, const char *value, int length, pmdaExt *pmda) { int id = -1; if (pmDebug & DBG_TRACE_APPL0) __pmNotifyErr(LOG_DEBUG, "attribute callback context %d attr=%d id==%d\n", context, attr, atoi(value)); enlarge_ctxtab(context); assert(ctxtab != NULL && context < ctxtab_size); if (attr != PCP_ATTR_USERID) return 0; ctxtab[context].uid_flag = 1; ctxtab[context].uid = id = atoi(value); if (id != 0) { if (pmDebug & DBG_TRACE_AUTH) __pmNotifyErr(LOG_DEBUG, "access denied context %d attr=%d id=%d\n", context, attr, id); return PM_ERR_PERMISSION; } if (pmDebug & DBG_TRACE_AUTH) __pmNotifyErr(LOG_DEBUG, "access granted attr=%d id=%d\n", attr, id); return 0; }
/* * Connect to the pmdaroot socket as a client, perform version exchange */ int pmdaRootConnect(const char *path) { __pmSockAddr *addr; char *tmpdir; char socketpath[MAXPATHLEN]; char errmsg[PM_MAXERRMSGLEN]; int fd, sts, version, features; /* Initialize the socket address. */ if ((addr = __pmSockAddrAlloc()) == NULL) return -ENOMEM; if (path == NULL) { if ((tmpdir = pmGetOptionalConfig("PCP_TMP_DIR")) == NULL) { __pmSockAddrFree(addr); return PM_ERR_GENERIC; } snprintf(socketpath, sizeof(socketpath), "%s/pmcd/root.socket", tmpdir); } else strncpy(socketpath, path, sizeof(socketpath)); socketpath[sizeof(socketpath)-1] = '\0'; __pmSockAddrSetFamily(addr, AF_UNIX); __pmSockAddrSetPath(addr, socketpath); /* Create client socket connection */ if ((fd = __pmCreateUnixSocket()) < 0) { __pmNotifyErr(LOG_ERR, "pmdaRootConnect: cannot create socket %s: %s\n", socketpath, osstrerror_r(errmsg, sizeof(errmsg))); __pmSockAddrFree(addr); return fd; } sts = __pmConnect(fd, addr, -1); __pmSockAddrFree(addr); if (sts < 0) { if (sts != -EPERM || (pmDebug & DBG_TRACE_LIBPMDA)) __pmNotifyErr(LOG_INFO, "pmdaRootConnect: cannot connect to %s: %s\n", socketpath, osstrerror_r(errmsg, sizeof(errmsg))); __pmCloseSocket(fd); return sts; } /* Check server connection information */ if ((sts = __pmdaRecvRootPDUInfo(fd, &version, &features)) < 0) { __pmNotifyErr(LOG_ERR, "pmdaRootConnect: cannot verify %s server: %s\n", socketpath, pmErrStr_r(sts, errmsg, sizeof(errmsg))); __pmCloseSocket(fd); return sts; } if (pmDebug & DBG_TRACE_LIBPMDA) __pmNotifyErr(LOG_INFO, "pmdaRootConnect: %s server fd=%d version=%d features=0x%x\n", socketpath, fd, version, features); return fd; }
int host_state_changed(char *host, int state) { hstate_t *hsp; for (hsp = host_map; hsp != NULL; hsp = hsp->next) { if (strcmp(host, hsp->name) == 0) break; } if (hsp == NULL) { hsp = (hstate_t *)alloc(sizeof(*hsp)); hsp->next = host_map; hsp->name = sdup(host); hsp->state = STATE_INIT; host_map = hsp; } if (state == hsp->state) return 0; if (quiet) ; /* be quiet */ else if (state == STATE_FAILINIT) __pmNotifyErr(LOG_INFO, "Cannot connect to pmcd on host %s\n", host); else if (state == STATE_RECONN && hsp->state != STATE_INIT) __pmNotifyErr(LOG_INFO, "Re-established connection to pmcd on host %s\n", host); else if (state == STATE_LOSTCONN) __pmNotifyErr(LOG_INFO, "Lost connection to pmcd on host %s\n", host); hsp->state = state; return 1; }
/* Based on Stevens (Unix Network Programming, p.83) */ void pmweb_start_daemon(int argc, char **argv) { int childpid; (void)argc; (void)argv; #if defined(HAVE_TERMIO_SIGNALS) signal(SIGTTOU, SIG_IGN); signal(SIGTTIN, SIG_IGN); signal(SIGTSTP, SIG_IGN); #endif if ((childpid = fork()) < 0) __pmNotifyErr(LOG_ERR, "pmweb_start_daemon: fork"); /* but keep going */ else if (childpid > 0) { /* parent, let her exit, but avoid ugly "Log finished" messages */ fclose(stderr); exit(0); } /* not a process group leader, lose controlling tty */ if (setsid() == -1) __pmNotifyErr(LOG_WARNING, "pmweb_start_daemon: setsid"); /* but keep going */ close(0); /* don't close other fd's -- we know that only good ones are open! */ /* don't chdir("/") -- we still need to open pmcd.log */ }
/* * Hostname extracted and cached for later use during protocol negotiations */ static void GetProxyHostname(void) { __pmHostEnt *hep; char host[MAXHOSTNAMELEN]; if (gethostname(host, MAXHOSTNAMELEN) < 0) { __pmNotifyErr(LOG_ERR, "%s: gethostname failure\n", pmProgname); DontStart(); } host[MAXHOSTNAMELEN-1] = '\0'; hep = __pmGetAddrInfo(host); if (hep == NULL) { __pmNotifyErr(LOG_ERR, "%s: __pmGetAddrInfo failure\n", pmProgname); DontStart(); } else { hostname = __pmHostEntGetName(hep); if (!hostname) { /* no reverse DNS lookup for local hostname */ hostname = strdup(host); if (!hostname) /* out of memory, we're having a bad day!?! */ __pmNoMem("PMPROXY.hostname", strlen(host), PM_FATAL_ERR); } __pmHostEntFree(hep); } }
static int refresh_interrupts(pmdaExt *pmda, __pmnsTree **tree) { int i, sts, dom = pmda->e_domain; if (interrupt_tree) { *tree = interrupt_tree; } else if ((sts = __pmNewPMNS(&interrupt_tree)) < 0) { __pmNotifyErr(LOG_ERR, "%s: failed to create interrupt names: %s\n", pmProgname, pmErrStr(sts)); *tree = NULL; } else if ((sts = refresh_interrupt_values()) < 0) { __pmNotifyErr(LOG_ERR, "%s: failed to update interrupt values: %s\n", pmProgname, pmErrStr(sts)); *tree = NULL; } else { for (i = 0; i < lines_count; i++) update_lines_pmns(dom, i, interrupt_lines[i].id); for (i = 0; i < other_count; i++) update_other_pmns(dom, i, interrupt_other[i].name); *tree = interrupt_tree; pmdaTreeRebuildHash( interrupt_tree, lines_count+other_count ); return 1; } return 0; }
static int __pmAuthServerSetAttributes(sasl_conn_t *conn, __pmHashCtl *attrs) { const void *property = NULL; char *username; int sts; sts = sasl_getprop(conn, SASL_USERNAME, &property); username = (char *)property; if (sts == SASL_OK && username) { __pmNotifyErr(LOG_INFO, "Successful authentication for user \"%s\"\n", username); if ((username = strdup(username)) == NULL) { __pmNoMem("__pmAuthServerSetAttributes", strlen(username), PM_RECOV_ERR); return -ENOMEM; } } else { __pmNotifyErr(LOG_ERR, "Authentication complete, but no username\n"); return -ESRCH; } if ((sts = __pmHashAdd(PCP_ATTR_USERNAME, username, attrs)) < 0) return sts; return __pmSetUserGroupAttributes(username, attrs); }
static int __pmAuthServerSetProperties(sasl_conn_t *conn, int ssf) { int saslsts; sasl_security_properties_t props; /* set external security strength factor */ saslsts = sasl_setprop(conn, SASL_SSF_EXTERNAL, &ssf); if (saslsts != SASL_OK && saslsts != SASL_CONTINUE) { __pmNotifyErr(LOG_ERR, "SASL setting external SSF to %d: %s", ssf, sasl_errstring(saslsts, NULL, NULL)); return __pmSecureSocketsError(saslsts); } /* set general security properties */ memset(&props, 0, sizeof(props)); props.maxbufsize = LIMIT_AUTH_PDU; props.max_ssf = UINT_MAX; saslsts = sasl_setprop(conn, SASL_SEC_PROPS, &props); if (saslsts != SASL_OK && saslsts != SASL_CONTINUE) { __pmNotifyErr(LOG_ERR, "SASL setting security properties: %s", sasl_errstring(saslsts, NULL, NULL)); return __pmSecureSocketsError(saslsts); } return 0; }
static void SignalReloadPMNS(void) { int sts; /* Reload PMNS if necessary. * Note: this will only stat() the base name i.e. ASCII pmns, * typically $PCP_VAR_DIR/pmns/root and not $PCP_VAR_DIR/pmns/root.bin . * This is considered a very low risk problem, as the binary * PMNS is always compiled from the ASCII version; * when one changes so should the other. * This caveat was allowed to make the code a lot simpler. */ if (__pmHasPMNSFileChanged(pmnsfile)) { __pmNotifyErr(LOG_INFO, "Reloading PMNS \"%s\"", (pmnsfile==PM_NS_DEFAULT)?"DEFAULT":pmnsfile); pmUnloadNameSpace(); sts = pmLoadASCIINameSpace(pmnsfile, dupok); if (sts < 0) { __pmNotifyErr(LOG_ERR, "pmLoadASCIINameSpace(%s, %d): %s\n", (pmnsfile == PM_NS_DEFAULT) ? "DEFAULT" : pmnsfile, dupok, pmErrStr(sts)); } } else { __pmNotifyErr(LOG_INFO, "PMNS file \"%s\" is unchanged", (pmnsfile == PM_NS_DEFAULT) ? "DEFAULT" : pmnsfile); } }
static void SignalShutdown(void) { #ifdef HAVE_SA_SIGINFO #if DESPERATE char buf[256]; #endif if (killer_pid != 0) { __pmNotifyErr(LOG_INFO, "pmcd caught %s from pid=%" FMT_PID " uid=%d\n", killer_sig == SIGINT ? "SIGINT" : "SIGTERM", killer_pid, killer_uid); #if DESPERATE __pmNotifyErr(LOG_INFO, "Try to find process in ps output ...\n"); sprintf(buf, "sh -c \". \\$PCP_DIR/etc/pcp.env; ( \\$PCP_PS_PROG \\$PCP_PS_ALL_FLAGS | \\$PCP_AWK_PROG 'NR==1 {print} \\$2==%" FMT_PID " {print}' )\"", killer_pid); system(buf); #endif } else { __pmNotifyErr(LOG_INFO, "pmcd caught %s from unknown process\n", killer_sig == SIGINT ? "SIGINT" : "SIGTERM"); } #else __pmNotifyErr(LOG_INFO, "pmcd caught %s\n", killer_sig == SIGINT ? "SIGINT" : "SIGTERM"); #endif Shutdown(); exit(0); }
/* Establish a new socket connection to a client */ ClientInfo * AcceptNewClient(int reqfd) { static unsigned int seq = 0; int i, fd; __pmSockLen addrlen; struct timeval now; i = NewClient(); addrlen = __pmSockAddrSize(); fd = __pmAccept(reqfd, client[i].addr, &addrlen); if (fd == -1) { if (neterror() == EPERM) { __pmNotifyErr(LOG_NOTICE, "AcceptNewClient(%d): " "Permission Denied\n", reqfd); client[i].fd = -1; DeleteClient(&client[i]); return NULL; } else { __pmNotifyErr(LOG_ERR, "AcceptNewClient(%d) __pmAccept: %s\n", reqfd, netstrerror()); Shutdown(); exit(1); } } if (fd > maxClientFd) maxClientFd = fd; pmcd_openfds_sethi(fd); __pmFD_SET(fd, &clientFds); __pmSetVersionIPC(fd, UNKNOWN_VERSION); /* before negotiation */ __pmSetSocketIPC(fd); client[i].fd = fd; client[i].status.connected = 1; client[i].status.changes = 0; memset(&client[i].attrs, 0, sizeof(__pmHashCtl)); /* * Note seq needs to be unique, but we're using a free running counter * and not bothering to check here ... unless we churn through * 4,294,967,296 (2^32) clients while one client remains connected * we won't have a problem */ client[i].seq = seq++; __pmtimevalNow(&now); client[i].start = now.tv_sec; #ifdef PCP_DEBUG if (pmDebug & DBG_TRACE_APPL0) fprintf(stderr, "AcceptNewClient(%d): client[%d] (fd %d)\n", reqfd, i, fd); #endif pmcd_trace(TR_ADD_CLIENT, i, 0, 0); return &client[i]; }
static int negotiate_proxy(int fd, const char *hostname, int port) { char buf[MY_BUFLEN]; char *bp; int ok = 0; /* * version negotiation (converse to pmproxy logic) * __pmSend my client version message * __pmRecv server version message * __pmSend hostname and port */ if (__pmSend(fd, MY_VERSION, strlen(MY_VERSION), 0) != strlen(MY_VERSION)) { char errmsg[PM_MAXERRMSGLEN]; __pmNotifyErr(LOG_WARNING, "__pmConnectPMCD: send version string to pmproxy failed: %s\n", pmErrStr_r(-neterror(), errmsg, sizeof(errmsg))); return PM_ERR_IPC; } for (bp = buf; bp < &buf[MY_BUFLEN]; bp++) { if (__pmRecv(fd, bp, 1, 0) != 1) { *bp = '\0'; bp = &buf[MY_BUFLEN]; break; } if (*bp == '\n' || *bp == '\r') { *bp = '\0'; break; } } if (bp < &buf[MY_BUFLEN]) { if (strcmp(buf, "pmproxy-server 1") == 0) ok = 1; } if (!ok) { __pmNotifyErr(LOG_WARNING, "__pmConnectPMCD: bad version string from pmproxy: \"%s\"\n", buf); return PM_ERR_IPC; } snprintf(buf, sizeof(buf), "%s %d\n", hostname, port); if (__pmSend(fd, buf, strlen(buf), 0) != strlen(buf)) { char errmsg[PM_MAXERRMSGLEN]; __pmNotifyErr(LOG_WARNING, "__pmConnectPMCD: send hostname+port string to pmproxy failed: %s'\n", pmErrStr_r(-neterror(), errmsg, sizeof(errmsg))); return PM_ERR_IPC; } return ok; }
void loggerMain(pmdaInterface *dispatch) { fd_set readyfds; int nready, pmcdfd; pmcdfd = __pmdaInFd(dispatch); if (pmcdfd > maxfd) maxfd = pmcdfd; FD_ZERO(&fds); FD_SET(pmcdfd, &fds); /* arm interval timer */ if (__pmAFregister(&interval, NULL, logger_timer) < 0) { __pmNotifyErr(LOG_ERR, "registering event interval handler"); exit(1); } for (;;) { memcpy(&readyfds, &fds, sizeof(readyfds)); nready = select(maxfd+1, &readyfds, NULL, NULL, NULL); if (pmDebug & DBG_TRACE_APPL2) __pmNotifyErr(LOG_DEBUG, "select: nready=%d interval=%d", nready, interval_expired); if (nready < 0) { if (neterror() != EINTR) { __pmNotifyErr(LOG_ERR, "select failure: %s", netstrerror()); exit(1); } else if (!interval_expired) { continue; } } __pmAFblock(); if (nready > 0 && FD_ISSET(pmcdfd, &readyfds)) { if (pmDebug & DBG_TRACE_APPL0) __pmNotifyErr(LOG_DEBUG, "processing pmcd PDU [fd=%d]", pmcdfd); if (__pmdaMainPDU(dispatch) < 0) { __pmAFunblock(); exit(1); /* fatal if we lose pmcd */ } if (pmDebug & DBG_TRACE_APPL0) __pmNotifyErr(LOG_DEBUG, "completed pmcd PDU [fd=%d]", pmcdfd); } if (interval_expired) { interval_expired = 0; event_refresh(); } __pmAFunblock(); } }
/* * This routine opens the config file and stores the information in the * mounts structure. The mounts structure must be reallocated as * necessary, and also the num_procs structure needs to be reallocated * as we define new mounts. When all of that is done, we fill in the * values in the indomtab structure, those being the number of instances * and the pointer to the mounts structure. */ static void mounts_grab_config_info(void) { FILE *fp; char mount_name[MAXPATHLEN]; char *q; size_t size; int mount_number = 0; int sep = __pmPathSeparator(); snprintf(mypath, sizeof(mypath), "%s%c" "mounts" "%c" "mounts.conf", pmGetConfig("PCP_PMDAS_DIR"), sep, sep); if ((fp = fopen(mypath, "r")) == NULL) { __pmNotifyErr(LOG_ERR, "fopen on %s failed: %s\n", mypath, pmErrStr(-oserror())); if (mounts) { free(mounts); mounts = NULL; mount_number = 0; } goto done; } while (fgets(mount_name, sizeof(mount_name), fp) != NULL) { if (mount_name[0] == '#') continue; /* Remove the newline */ if ((q = strchr(mount_name, '\n')) != NULL) { *q = '\0'; } else { /* This means the line was too long */ __pmNotifyErr(LOG_WARNING, "line %d in the config file too long\n", mount_number+1); } size = (mount_number + 1) * sizeof(pmdaInstid); if ((mounts = realloc(mounts, size)) == NULL) __pmNoMem("process", size, PM_FATAL_ERR); mounts[mount_number].i_name = malloc(strlen(mount_name) + 1); strcpy(mounts[mount_number].i_name, mount_name); mounts[mount_number].i_inst = mount_number; mount_number++; } fclose(fp); done: if (mounts == NULL) __pmNotifyErr(LOG_WARNING, "\"mounts\" instance domain is empty"); indomtab[MOUNTS_INDOM].it_set = mounts; indomtab[MOUNTS_INDOM].it_numinst = mount_number; mount_list = realloc(mount_list, (mount_number)*sizeof(mountinfo)); }
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(__pmLock_libpcp); secsts = SSL_ConfigSecureServer(sslsocket, secure_server.certificate, secure_server.private_key, secure_server.certificate_KEA); PM_UNLOCK(__pmLock_libpcp); 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; }
/* * Parse our stomp configuration file, simple format: * host=<hostname> # JMS server machine * port=<port#> # server port number * username=<user> | user=<user> * passcode=<password> | password=<password> * timeout=<seconds> # optional * topic=<JMStopic> # optional */ static void stomp_parse(void) { char config[MAXPATHLEN+1]; FILE *f; int sep = __pmPathSeparator(); if (stompfile) strncat(config, stompfile, sizeof(config)-1); else snprintf(config, sizeof(config), "%s%c" "config" "%c" "pmie" "%c" "stomp", pmGetConfig("PCP_VAR_DIR"), sep, sep, sep); if ((f = fopen(config, "r")) == NULL) { __pmNotifyErr(LOG_ERR, "Cannot open STOMP configuration file %s: %s", config, osstrerror()); exit(1); } while (fgets(buffer, sizeof(buffer), f)) { if (strncmp(buffer, "port=", 5) == 0) port = atoi(isspace_terminate(&buffer[5])); else if (strncmp(buffer, "host=", 5) == 0) hostname = strdup(isspace_terminate(&buffer[5])); else if (strncmp(buffer, "hostname=", 9) == 0) hostname = strdup(isspace_terminate(&buffer[9])); else if (strncmp(buffer, "user="******"username="******"password="******"passcode=", 9) == 0) passcode = strdup(isspace_terminate(&buffer[9])); else if (strncmp(buffer, "timeout=", 8) == 0) /* optional */ timeout = atoi(isspace_terminate(&buffer[8])); else if (strncmp(buffer, "topic=", 6) == 0) /* optional */ topic = strdup(isspace_terminate(&buffer[6])); } fclose(f); if (!hostname) __pmNotifyErr(LOG_ERR, "No host in STOMP config file %s", config); if (port == -1) __pmNotifyErr(LOG_ERR, "No port in STOMP config file %s", config); if (!username) __pmNotifyErr(LOG_ERR, "No username in STOMP config file %s", config); if (!passcode) __pmNotifyErr(LOG_ERR, "No passcode in STOMP config file %s", config); if (port == -1 || !hostname || !username || !passcode) exit(1); }
void event_init(pmID pmid) { char cmd[MAXPATHLEN]; int i, fd; for (i = 0; i < numlogfiles; i++) { size_t pathlen = strlen(logfiles[i].pathname); /* * We support 2 kinds of PATHNAMEs: * (1) Regular paths. These paths are opened normally. * (2) Pipes. If the path ends in '|', the filename is * interpreted as a command which pipes input to us. */ if (logfiles[i].pathname[pathlen - 1] != '|') { fd = open(logfiles[i].pathname, O_RDONLY|O_NONBLOCK); if (fd < 0) { if (logfiles[i].fd >= 0) /* log once only */ __pmNotifyErr(LOG_ERR, "open: %s - %s", logfiles[i].pathname, strerror(errno)); } else { if (fstat(fd, &logfiles[i].pathstat) < 0) if (logfiles[i].fd >= 0) /* log once only */ __pmNotifyErr(LOG_ERR, "fstat: %s - %s", logfiles[i].pathname, strerror(errno)); lseek(fd, 0, SEEK_END); } } else { strncpy(cmd, logfiles[i].pathname, sizeof(cmd)); cmd[pathlen - 1] = '\0'; /* get rid of the '|' */ rstrip(cmd); /* Remove all trailing whitespace. */ fd = start_cmd(cmd, &logfiles[i].pid); if (fd < 0) { if (logfiles[i].fd >= 0) /* log once only */ __pmNotifyErr(LOG_ERR, "pipe: %s - %s", logfiles[i].pathname, strerror(errno)); } else { if (fd > maxfd) maxfd = fd; FD_SET(fd, &fds); } } logfiles[i].fd = fd; /* keep file descriptor (or error) */ logfiles[i].pmid = pmid; /* string param metric identifier */ logfiles[i].queueid = pmdaEventNewQueue(logfiles[i].pmnsname, maxmem); } }
int pmdaAttribute(int ctx, int attr, const char *value, int size, pmdaExt *pmda) { if (pmDebug & (DBG_TRACE_ATTR|DBG_TRACE_AUTH)) { char buffer[256]; if (!__pmAttrStr_r(attr, value, buffer, sizeof(buffer))) { __pmNotifyErr(LOG_ERR, "Bad attr: ctx=%d, attr=%d\n", ctx, attr); } else { buffer[sizeof(buffer)-1] = '\0'; __pmNotifyErr(LOG_INFO, "Attribute: ctx=%d %s", ctx, buffer); } } return 0; }
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); }
static void DontStart(void) { FILE *tty; FILE *log; __pmNotifyErr(LOG_ERR, "pmcd not started due to errors!\n"); if ((tty = fopen(fatalfile, "w")) != NULL) { fflush(stderr); fprintf(tty, "NOTE: pmcd not started due to errors! "); if ((log = fopen(logfile, "r")) != NULL) { int c; fprintf(tty, "Log file \"%s\" contains ...\n", logfile); while ((c = fgetc(log)) != EOF) fputc(c, tty); fclose(log); } else fprintf(tty, "Log file \"%s\" has vanished!\n", logfile); fclose(tty); } /* * We are often called after the request ports have been opened. If we don't * explicitely close them, then the unix domain socket file (if any) will be * left in the file system, causing "address already in use" the next time * pmcd starts. */ __pmServerCloseRequestPorts(); exit(1); }
void __pmServerCloseRequestPorts(void) { int i, fd; for (i = 0; i < nReqPorts; i++) { /* No longer advertise our presence on the network. */ if (reqPorts[i].presence != NULL) __pmServerUnadvertisePresence(reqPorts[i].presence); if ((fd = reqPorts[i].fds[INET_FD]) >= 0) __pmCloseSocket(fd); if ((fd = reqPorts[i].fds[IPV6_FD]) >= 0) __pmCloseSocket(fd); } #if defined(HAVE_STRUCT_SOCKADDR_UN) if (localSocketFd >= 0) { __pmCloseSocket(localSocketFd); localSocketFd = -EPROTO; /* We must remove the socket file. */ if (unlink(localSocketPath) != 0 && oserror() != ENOENT) { char errmsg[PM_MAXERRMSGLEN]; __pmNotifyErr(LOG_ERR, "%s: can't unlink %s (uid=%d,euid=%d): %s", pmProgname, localSocketPath, getuid(), geteuid(), osstrerror_r(errmsg, sizeof(errmsg))); } } #endif }
static int __pmSetUserGroupAttributes(const char *username, __pmHashCtl *attrs) { char name[32]; char *namep; uid_t uid; gid_t gid; if (__pmGetUserIdentity(username, &uid, &gid, PM_RECOV_ERR) == 0) { snprintf(name, sizeof(name), "%u", uid); name[sizeof(name)-1] = '\0'; if ((namep = strdup(name)) != NULL) __pmHashAdd(PCP_ATTR_USERID, namep, attrs); else return -ENOMEM; snprintf(name, sizeof(name), "%u", gid); name[sizeof(name)-1] = '\0'; if ((namep = strdup(name)) != NULL) __pmHashAdd(PCP_ATTR_GROUPID, namep, attrs); else return -ENOMEM; return 0; } __pmNotifyErr(LOG_ERR, "Authenticated user %s not found\n", username); return -ESRCH; }
static int do_creds(__pmPDU *pb) { int i; int sts; int version = UNKNOWN_VERSION; int credcount; int sender; __pmCred *credlist = NULL; if ((sts = __pmDecodeCreds(pb, &sender, &credcount, &credlist)) < 0) { __pmNotifyErr(LOG_ERR, "do_creds: error decoding PDU: %s\n", pmErrStr(sts)); return PM_ERR_IPC; } for (i = 0; i < credcount; i++) { if (credlist[i].c_type == CVERSION) { version = credlist[i].c_vala; if ((sts = __pmSetVersionIPC(clientfd, version)) < 0) { free(credlist); return sts; } } } if (credlist) free(credlist); #ifdef PCP_DEBUG if (pmDebug & DBG_TRACE_APPL1) fprintf(stderr, "do_creds: pmlc version=%d\n", version); #endif return sts; }
int __pmdaCntInst(pmInDom indom, pmdaExt *pmda) { int i; int sts = 0; if (indom == PM_INDOM_NULL) return 1; if (pmdaCacheOp(indom, PMDA_CACHE_CHECK)) { sts = pmdaCacheOp(indom, PMDA_CACHE_SIZE_ACTIVE); } else { for (i = 0; i < pmda->e_nindoms; i++) { if (pmda->e_indoms[i].it_indom == indom) { sts = pmda->e_indoms[i].it_numinst; break; } } if (i == pmda->e_nindoms) { char strbuf[20]; __pmNotifyErr(LOG_WARNING, "cntinst: unknown indom %s", pmInDomStr_r(indom, strbuf, sizeof(strbuf))); } } #ifdef PCP_DEBUG if (pmDebug & DBG_TRACE_INDOM) { char strbuf[20]; fprintf(stderr, "__pmdaCntInst(indom=%s) -> %d\n", pmInDomStr_r(indom, strbuf, sizeof(strbuf)), sts); } #endif return sts; }
int pmdaDesc(pmID pmid, pmDesc *desc, pmdaExt *pmda) { e_ext_t *extp = (e_ext_t *)pmda->e_ext; pmdaMetric *metric; char strbuf[32]; if (extp->dispatch->comm.pmda_interface >= PMDA_INTERFACE_5) __pmdaSetContext(pmda->e_context); if (pmda->e_flags & PMDA_EXT_FLAG_HASHED) metric = __pmdaHashedSearch(pmid, &extp->hashpmids); else if (pmda->e_direct) metric = __pmdaDirectSearch(pmid, pmda); else metric = __pmdaLinearSearch(pmid, pmda); if (metric) { *desc = metric->m_desc; return 0; } __pmNotifyErr(LOG_ERR, "pmdaDesc: Requested metric %s is not defined", pmIDStr_r(pmid, strbuf, sizeof(strbuf))); return PM_ERR_PMID; }
void SignalShutdown(void) { __pmNotifyErr(LOG_INFO, "pmproxy caught SIGINT or SIGTERM\n"); Shutdown(); exit(0); }
/* Loop, synchronously processing requests from clients. */ static void ClientLoop(void) { int i, sts; int maxFd; __pmFdSet readableFds; for (;;) { /* Figure out which file descriptors to wait for input on. Keep * track of the highest numbered descriptor for the select call. */ readableFds = sockFds; maxFd = maxSockFd + 1; sts = __pmSelectRead(maxFd, &readableFds, NULL); if (sts > 0) { if (pmDebug & DBG_TRACE_APPL0) for (i = 0; i <= maxSockFd; i++) if (__pmFD_ISSET(i, &readableFds)) fprintf(stderr, "__pmSelectRead(): from %s fd=%d\n", FdToString(i), i); __pmServerAddNewClients(&readableFds, CheckNewClient); HandleInput(&readableFds); } else if (sts == -1 && neterror() != EINTR) { __pmNotifyErr(LOG_ERR, "ClientLoop select: %s\n", netstrerror()); break; } if (timeToDie) { SignalShutdown(); break; } } }
static void mounts_config_file_check(void) { struct stat statbuf; static int last_error; int sep = __pmPathSeparator(); snprintf(mypath, sizeof(mypath), "%s%c" "mounts" "%c" "mounts.conf", pmGetConfig("PCP_PMDAS_DIR"), sep, sep); if (stat(mypath, &statbuf) == -1) { if (oserror() != last_error) { last_error = oserror(); __pmNotifyErr(LOG_WARNING, "stat failed on %s: %s\n", mypath, pmErrStr(last_error)); } } else { last_error = 0; #if defined(HAVE_ST_MTIME_WITH_E) if (statbuf.st_mtime != file_change.st_mtime) #elif defined(HAVE_ST_MTIME_WITH_SPEC) if (statbuf.st_mtimespec.tv_sec != file_change.st_mtimespec.tv_sec || statbuf.st_mtimespec.tv_nsec != file_change.st_mtimespec.tv_nsec) #else if (statbuf.st_mtim.tv_sec != file_change.st_mtim.tv_sec || statbuf.st_mtim.tv_nsec != file_change.st_mtim.tv_nsec) #endif { mounts_clear_config_info(); mounts_grab_config_info(); file_change = statbuf; } } }
void netlink_update_stats(int fetch) { kstat_t *k; kstat_ctl_t *kc; pmInDom indom = indomtab[NETLINK_INDOM].it_indom; if ((kc = kstat_ctl_update()) == NULL) return; for (k = kc->kc_chain; k != NULL; k = k->ks_next) { if (strcmp(k->ks_module, "link") == 0) { int rv; kstat_t *cached; if (pmdaCacheLookupName(indom, k->ks_name, &rv, (void **)&cached) != PMDA_CACHE_ACTIVE) { rv = pmdaCacheStore(indom, PMDA_CACHE_ADD, k->ks_name, k); if (rv < 0) { __pmNotifyErr(LOG_WARNING, "Cannot create instance for " "network link '%s': %s\n", k->ks_name, pmErrStr(rv)); continue; } } if (fetch) kstat_read(kc, k, NULL); } } }
static int etw_fetch(int numpmid, pmID pmidlist[], pmResult **resp, pmdaExt *pmda) { __pmNotifyErr(LOG_WARNING, "called %s", __FUNCTION__); pmdaEventNewClient(pmda->e_context); return pmdaFetch(numpmid, pmidlist, resp, pmda); }