Пример #1
0
void
ShowClients(FILE *f)
{
    int			i;
    char		*sbuf;
    char		*hostName;

    fprintf(f, "     fd  client connection from                    ipc ver  operations denied\n");
    fprintf(f, "     ==  ========================================  =======  =================\n");
    for (i = 0; i < nClients; i++) {
	if (client[i].status.connected == 0)
	    continue;

	fprintf(f, "    %3d  ", client[i].fd);

	hostName = __pmGetNameInfo(client[i].addr);
	if (hostName == NULL) {
	    sbuf = __pmSockAddrToString(client[i].addr);
	    fprintf(f, "%s", sbuf);
	    free(sbuf);
	} else {
	    fprintf(f, "%-40.40s", hostName);
	    free(hostName);
	}
	fprintf(f, "  %7d", __pmVersionIPC(client[i].fd));

	if (client[i].denyOps != 0) {
	    fprintf(f, "  ");
	    if (client[i].denyOps & PMCD_OP_FETCH)
		fprintf(f, "fetch ");
	    if (client[i].denyOps & PMCD_OP_STORE)
		fprintf(f, "store ");
	}

	fputc('\n', f);
    }
    fputc('\n', f);
}
Пример #2
0
Файл: util.c Проект: scotte/pcp
void
dostatus(void)
{
    int		i = 0;
    int		n;

    putchar('\n');
    printf("Namespace:              ");
    if (cmd_namespace != NULL)
        printf("%s\n", cmd_namespace);
    else {
        if (pmnsfile == NULL)
            printf("(default)\n");
	else
            printf("%s\n", pmnsfile);
    }

    if (myPmdaName == NULL || connmode == NO_CONN)
	printf("PMDA:                   none\n");
    else {
	printf("PMDA:                   %s\n", myPmdaName);
	printf("Connection:             ");
	switch (connmode) {
	case CONN_DSO:
	    printf("dso\n");
	    printf("DSO Interface Version:  %d\n", dispatch.comm.pmda_interface);
	    printf("PMDA PMAPI Version:     %d\n", dispatch.comm.pmapi_version);
	    break;
	case CONN_DAEMON:
	    printf("daemon\n");
	    printf("PMDA PMAPI Version:     ");
	    i = __pmVersionIPC(infd);
	    if (i == UNKNOWN_VERSION)
		printf("unknown!\n");
	    else
		printf("%d\n", i);
	    break;
	default:
	    printf("unknown!\n");
	    break;
	}
    }

    printf("Debug options:          ");
    n = 0;
    for (i = 0; i < num_debug; i++) {
	if (*(debug_map[i].options))
	    n++;
    }
    if (n == num_debug)
	printf("(all)");
    else if (n == 0)
	printf("(none)");
    else {
	n = 0;
	for (i = 0; i < num_debug; i++) {
	    if (*(debug_map[i].options)) {
		if (n == 0)
		    n = 1;
		else
		    putchar(' ');
		printf("%s", debug_map[i].name);
	    }
	}
    }
    putchar('\n');

    printf("Timer:                  ");
    if (timer == 0)
	printf("off\n");
    else
	printf("on\n");

    printf("Getdesc:                ");
    if (get_desc == 0)
	printf("off\n");
    else
	printf("on\n");

    putchar('\n');
    __pmDumpProfile(stdout, PM_INDOM_NULL, profile);
    putchar('\n');
}
Пример #3
0
/*
 * sendstatus
 */
static int
sendstatus(void)
{
    int				rv;
    int				end;
    int				version;
    static int			firsttime = 1;
    static char			*tzlogger;
    struct timeval		now;

    if (firsttime) {
        tzlogger = __pmTimezone();
	firsttime = 0;
    }

    if ((version = __pmVersionIPC(clientfd)) < 0)
	return version;

    if (version >= LOG_PDU_VERSION2) {
	__pmLoggerStatus		ls;

	if ((ls.ls_state = logctl.l_state) == PM_LOG_STATE_NEW)
	    ls.ls_start.tv_sec = ls.ls_start.tv_usec = 0;
	else
	    memcpy(&ls.ls_start, &logctl.l_label.ill_start, sizeof(ls.ls_start));
	memcpy(&ls.ls_last, &last_stamp, sizeof(ls.ls_last));
	__pmtimevalNow(&now);
	ls.ls_timenow.tv_sec = (__int32_t)now.tv_sec;
	ls.ls_timenow.tv_usec = (__int32_t)now.tv_usec;
	ls.ls_vol = logctl.l_curvol;
	ls.ls_size = ftell(logctl.l_mfp);
	assert(ls.ls_size >= 0);

	/* be careful of buffer size mismatches when copying strings */
	end = sizeof(ls.ls_hostname) - 1;
	strncpy(ls.ls_hostname, logctl.l_label.ill_hostname, end);
	ls.ls_hostname[end] = '\0';
        /* BTW, that string should equal pmcd_host[]. */

        /* NB: FQDN cleanup: there is no such thing as 'the fully
           qualified domain name' of a server: it may have several or
           none; the set may have changed since the time the log
           archive was collected.  Now that we store the then-current
           pmcd.hostname in the ill_hostname (and thus get it reported
           in ls_hostname), we could pass something else informative
           in the ls_fqdn slot.  Namely, pmcd_host_conn[], which is the
           access path pmlogger's using to get to the pmcd. */
	end = sizeof(ls.ls_fqdn) - 1;
        strncpy(ls.ls_fqdn, pmcd_host_conn, end);
	ls.ls_fqdn[end] = '\0';

	end = sizeof(ls.ls_tz) - 1;
	strncpy(ls.ls_tz, logctl.l_label.ill_tz, end);
	ls.ls_tz[end] = '\0';
	end = sizeof(ls.ls_tzlogger) - 1;
	if (tzlogger != NULL)
	    strncpy(ls.ls_tzlogger, tzlogger, end);
	else
	    end = 0;
	ls.ls_tzlogger[end] = '\0';

	rv = __pmSendLogStatus(clientfd, &ls);
    }
    else
	rv = PM_ERR_IPC;
    return rv;
}
Пример #4
0
int
__pmConnectPMCD(pmHostSpec *hosts, int nhosts, int ctxflags, __pmHashCtl *attrs)
{
    int		sts = -1;
    int		fd = -1;	/* Fd for socket connection to pmcd */
    int		*ports;
    int		nports;
    int		portIx;
    int		version = -1;
    int		proxyport;
    pmHostSpec	*proxyhost;

    static int first_time = 1;
    static pmHostSpec proxy;

    PM_INIT_LOCKS();
    PM_LOCK(__pmLock_libpcp);
    if (first_time) {
	/*
	 * One-trip check for use of pmproxy(1) in lieu of pmcd(1),
	 * and to extract the optional environment variables ...
	 * PMCD_PORT, PMPROXY_HOST and PMPROXY_PORT.
	 * We also check for the presense of a certificate database
	 * and load it up if either a user or system (global) DB is
	 * found.
	 */
	first_time = 0;
	load_pmcd_ports();
	load_proxy_hostspec(&proxy);
    }

    if (hosts[0].nports == 0) {
	nports = global_nports;
	ports = global_portlist;
    }
    else {
	nports = hosts[0].nports;
	ports = hosts[0].ports;
    }

    if (proxy.name == NULL && nhosts == 1) {
	const char *name = (const char *)hosts[0].name;

	/*
	 * no proxy, connecting directly to pmcd
	 */
	PM_UNLOCK(__pmLock_libpcp);

	sts = -1;
	/* Try connecting via the local unix domain socket, if requested and supported. */
	if (nports == PM_HOST_SPEC_NPORTS_LOCAL || nports == PM_HOST_SPEC_NPORTS_UNIX) {
#if defined(HAVE_STRUCT_SOCKADDR_UN)
	    if ((fd = __pmAuxConnectPMCDUnixSocket(name)) >= 0) {
		if ((sts = __pmConnectHandshake(fd, name, ctxflags, attrs)) < 0) {
		    __pmCloseSocket(fd);
		}
		else
		    sts = fd;
		portIx = -1; /* no port */
	    }
#endif
	    /*
	     * If the connection failed, or is not supported, and the protocol was 'local:',
	     * then try connecting to localhost via the default port(s).
	     */
	    if (sts < 0) {
		if (nports == PM_HOST_SPEC_NPORTS_LOCAL) {
		    name = "localhost";
		    nports = global_nports;
		    ports = global_portlist;
		    sts = -1; /* keep trying */
		}
		else
		    sts = -2; /* no more connection attempts. */
	    }
	}

	/* If still not connected, try via the given host name and ports, if requested. */
	if (sts == -1) {
	    for (portIx = 0; portIx < nports; portIx++) {
		if ((fd = __pmAuxConnectPMCDPort(name, ports[portIx])) >= 0) {
		    if ((sts = __pmConnectHandshake(fd, name, ctxflags, attrs)) < 0) {
			__pmCloseSocket(fd);
		    }
		    else
			/* success */
			break;
		}
		else
		    sts = fd;
	    }
	}

	if (sts < 0) {
#ifdef PCP_DEBUG
	    if (pmDebug & DBG_TRACE_CONTEXT) {
		char	errmsg[PM_MAXERRMSGLEN];
		fprintf(stderr, "__pmConnectPMCD(%s): pmcd connection port=",
		   hosts[0].name);
		for (portIx = 0; portIx < nports; portIx++) {
		    if (portIx == 0) fprintf(stderr, "%d", ports[portIx]);
		    else fprintf(stderr, ",%d", ports[portIx]);
		}
		fprintf(stderr, " failed: %s\n", pmErrStr_r(sts, errmsg, sizeof(errmsg)));
	    }
#endif
	    return sts;
	}

#ifdef PCP_DEBUG
	if (pmDebug & DBG_TRACE_CONTEXT) {
	    if (portIx >= 0) {
		fprintf(stderr, "__pmConnectPMCD(%s): pmcd connection port=%d fd=%d PDU version=%u\n",
			hosts[0].name, ports[portIx], fd, __pmVersionIPC(fd));
	    }
	    else {
		fprintf(stderr, "__pmConnectPMCD(%s): pmcd connection path=%s fd=%d PDU version=%u\n",
			hosts[0].name, name, fd, __pmVersionIPC(fd));
	    }
	    __pmPrintIPC();
	}
#endif

	return fd;
    }

    /*
     * connecting to pmproxy, and then to pmcd ... not a direct
     * connection to pmcd
     */
    proxyhost = (nhosts > 1) ? &hosts[1] : &proxy;
    proxyport = (proxyhost->nports > 0) ? proxyhost->ports[0] : PROXY_PORT;

    for (portIx = 0; portIx < nports; portIx++) {
	fd = __pmAuxConnectPMCDPort(proxyhost->name, proxyport);
	if (fd < 0) {
#ifdef PCP_DEBUG
	    if (pmDebug & DBG_TRACE_CONTEXT) {
		char	errmsg[PM_MAXERRMSGLEN];
		fprintf(stderr, "__pmConnectPMCD(%s): proxy to %s port=%d failed: %s \n",
			hosts[0].name, proxyhost->name, proxyport, pmErrStr_r(-neterror(), errmsg, sizeof(errmsg)));
	    }
#endif
	    PM_UNLOCK(__pmLock_libpcp);
	    return fd;
	}
	if ((sts = version = negotiate_proxy(fd, hosts[0].name, ports[portIx])) < 0)
	    __pmCloseSocket(fd);
	else if ((sts = __pmConnectHandshake(fd, proxyhost->name, ctxflags, attrs)) < 0)
	    __pmCloseSocket(fd);
	else
	    /* success */
	    break;
    }

    if (sts < 0) {
#ifdef PCP_DEBUG
	if (pmDebug & DBG_TRACE_CONTEXT) {
	    char	errmsg[PM_MAXERRMSGLEN];
	    fprintf(stderr, "__pmConnectPMCD(%s): proxy connection to %s port=",
			hosts[0].name, proxyhost->name);
	    for (portIx = 0; portIx < nports; portIx++) {
		if (portIx == 0) fprintf(stderr, "%d", ports[portIx]);
		else fprintf(stderr, ",%d", ports[portIx]);
	    }
	    fprintf(stderr, " failed: %s\n", pmErrStr_r(sts, errmsg, sizeof(errmsg)));
	}
#endif
	PM_UNLOCK(__pmLock_libpcp);
	return sts;
    }

#ifdef PCP_DEBUG
    if (pmDebug & DBG_TRACE_CONTEXT) {
	fprintf(stderr, "__pmConnectPMCD(%s): proxy connection host=%s port=%d fd=%d version=%d\n",
	    hosts[0].name, proxyhost->name, ports[portIx], fd, version);
    }
#endif

    PM_UNLOCK(__pmLock_libpcp);
    return fd;
}
Пример #5
0
/*
 * Determine which clients (if any) have sent data to the server and handle it
 * as required.
 */
void
HandleClientInput(__pmFdSet *fdsPtr)
{
    int		sts;
    int		i;
    __pmPDU	*pb;
    __pmPDUHdr	*php;
    ClientInfo	*cp;

    for (i = 0; i < nClients; i++) {
	int		pinpdu;
	if (!client[i].status.connected || !__pmFD_ISSET(client[i].fd, fdsPtr))
	    continue;

	cp = &client[i];
	this_client_id = i;

	pinpdu = sts = __pmGetPDU(cp->fd, LIMIT_SIZE, _pmcd_timeout, &pb);
	if (sts > 0) {
	    pmcd_trace(TR_RECV_PDU, cp->fd, sts, (int)((__psint_t)pb & 0xffffffff));
	} else {
	    CleanupClient(cp, sts);
	    continue;
	}

	php = (__pmPDUHdr *)pb;
	if (__pmVersionIPC(cp->fd) == UNKNOWN_VERSION && php->type != PDU_CREDS) {
	    /* old V1 client protocol, no longer supported */
	    sts = PM_ERR_IPC;
	    CleanupClient(cp, sts);
	    __pmUnpinPDUBuf(pb);
	    continue;
	}

	if (pmDebug & DBG_TRACE_APPL0)
	    ShowClients(stderr);

	switch (php->type) {
	    case PDU_PROFILE:
		sts = (cp->denyOps & PMCD_OP_FETCH) ?
		      PM_ERR_PERMISSION : DoProfile(cp, pb);
		break;

	    case PDU_FETCH:
		sts = (cp->denyOps & PMCD_OP_FETCH) ?
		      PM_ERR_PERMISSION : DoFetch(cp, pb);
		break;

	    case PDU_INSTANCE_REQ:
		sts = (cp->denyOps & PMCD_OP_FETCH) ?
		      PM_ERR_PERMISSION : DoInstance(cp, pb);
		break;

	    case PDU_DESC_REQ:
		sts = (cp->denyOps & PMCD_OP_FETCH) ?
		      PM_ERR_PERMISSION : DoDesc(cp, pb);
		break;

	    case PDU_TEXT_REQ:
		sts = (cp->denyOps & PMCD_OP_FETCH) ?
		      PM_ERR_PERMISSION : DoText(cp, pb);
		break;

	    case PDU_RESULT:
		sts = (cp->denyOps & PMCD_OP_STORE) ?
		      PM_ERR_PERMISSION : DoStore(cp, pb);
		break;

	    case PDU_PMNS_IDS:
		sts = (cp->denyOps & PMCD_OP_FETCH) ?
		      PM_ERR_PERMISSION : DoPMNSIDs(cp, pb);
		break;

	    case PDU_PMNS_NAMES:
		sts = (cp->denyOps & PMCD_OP_FETCH) ?
		      PM_ERR_PERMISSION : DoPMNSNames(cp, pb);
		break;

	    case PDU_PMNS_CHILD:
		sts = (cp->denyOps & PMCD_OP_FETCH) ?
		      PM_ERR_PERMISSION : DoPMNSChild(cp, pb);
		break;

	    case PDU_PMNS_TRAVERSE:
		sts = (cp->denyOps & PMCD_OP_FETCH) ?
		      PM_ERR_PERMISSION : DoPMNSTraverse(cp, pb);
		break;

	    case PDU_CREDS:
		sts = DoCreds(cp, pb);
		break;

	    default:
		sts = PM_ERR_IPC;
	}
	if (sts < 0) {
	    if (pmDebug & DBG_TRACE_APPL0)
		fprintf(stderr, "PDU:  %s client[%d]: %s\n",
		    __pmPDUTypeStr(php->type), i, pmErrStr(sts));
	    /* Make sure client still alive before sending. */
	    if (cp->status.connected) {
		pmcd_trace(TR_XMIT_PDU, cp->fd, PDU_ERROR, sts);
		sts = __pmSendError(cp->fd, FROM_ANON, sts);
		if (sts < 0)
		    __pmNotifyErr(LOG_ERR, "HandleClientInput: "
			"error sending Error PDU to client[%d] %s\n", i, pmErrStr(sts));
	    }
	}
	if (pinpdu > 0)
	    __pmUnpinPDUBuf(pb);
    }
}