diff options
Diffstat (limited to 'qa/src/pmcdgone.c')
-rw-r--r-- | qa/src/pmcdgone.c | 414 |
1 files changed, 414 insertions, 0 deletions
diff --git a/qa/src/pmcdgone.c b/qa/src/pmcdgone.c new file mode 100644 index 0000000..ed3c43d --- /dev/null +++ b/qa/src/pmcdgone.c @@ -0,0 +1,414 @@ +/* + * Copyright (c) 2012 Red Hat. All Rights Reserved. + * Copyright (c) 1997-2001 Silicon Graphics, Inc. All Rights Reserved. + */ + +/* + * ping pmcd 4 times, kill off pmcd, ping 4 more times, restart pmcd, + * ping 4 more times ... and some reconnect attempts for good measure ... + * and some more pings ... + * sleep 10 seconds after change of state for pmcd + * + * Has to be run as root to control pmcd + */ + +#include <ctype.h> +#include <pcp/pmapi.h> +#include <pcp/impl.h> + +#include "localconfig.h" + +static pmResult *_store; +static pmDesc _desc; +static int _numinst; +static int *_instlist; +static char **_inamelist; +static int _text; +static int _indom_text; +static int ctlport; + +static void +_ConnectLogger(void) +{ + int n; + int pid = PM_LOG_PRIMARY_PID; + int port = PM_LOG_NO_PORT; + + if ((n = __pmConnectLogger("localhost", &pid, &port)) < 0) { + printf("Cannot connect to primary pmlogger on \"localhost\": %s\n", pmErrStr(n)); + exit(1); + } + ctlport = n; +} + +static int +x_indom(int xpecterr) +{ + int err = 0; + int n; + int j; + int numinst; + int *instlist; + char **inamelist; + char *name = NULL; + + if ((numinst = pmGetInDom(_desc.indom, &instlist, &inamelist)) < 0) { + fprintf(stderr, "pmGetInDom: %s", pmErrStr(numinst)); + if (xpecterr) + fprintf(stderr, " -- error expected\n"); + else { + fprintf(stderr, "\n"); + err++; + } + } + else { + free(instlist); + free(inamelist); + } + + j = _numinst / 2; + + if ((n = pmNameInDom(_desc.indom, _instlist[j], &name)) < 0) { + fprintf(stderr, "pmNameInDom: %s", pmErrStr(n)); + if (xpecterr) + fprintf(stderr, " -- error expected\n"); + else { + fprintf(stderr, "\n"); + err++; + } + } + + if ((n = pmLookupInDom(_desc.indom, name)) < 0) { + fprintf(stderr, "pmLookupInDom: %s", pmErrStr(n)); + if (xpecterr) + fprintf(stderr, " -- error expected\n"); + else { + fprintf(stderr, "\n"); + err++; + } + } + else { + if (n != _instlist[j]) { + err++; + fprintf(stderr, "botch: pmLookupInDom returns 0x%x, expected 0x%x\n", + n, _instlist[j]); + } + free(name); + } + + return err; +} + +static int +exer(int numpmid, pmID *pmidlist, int xpecterr) +{ + int i; + int j; + int n; + int err = 0; + pmDesc desc; + char *buf; + pmResult *resp, *lresp; + + for (i = 0; i < 4; i++) { + if (!xpecterr) + fputc('.', stderr); + + if ((n = pmLookupDesc(pmidlist[0], &desc)) < 0) { + fprintf(stderr, "pmLookupDesc: %s", pmErrStr(n)); + if (xpecterr) + fprintf(stderr, " -- error expected\n"); + else { + fprintf(stderr, "\n"); + err++; + } + } + else if (xpecterr) + err++; + + err += x_indom(xpecterr); + + if ((n = pmLookupText(pmidlist[1], PM_TEXT_HELP, &buf)) < 0) { + fprintf(stderr, "pmLookupText: %s", pmErrStr(n)); + if (xpecterr) + fprintf(stderr, " -- error expected\n"); + else { + fprintf(stderr, "\n"); + err++; + } + } + else { + if (xpecterr) + err++; + if (!_text) { + fprintf(stderr, "Text: %s\n", buf); + _text = 1; + } + free(buf); + } + + if ((n = pmLookupInDomText(_desc.indom, PM_TEXT_HELP, &buf)) < 0) { + fprintf(stderr, "pmLookupInDomText: %s", pmErrStr(n)); + if (xpecterr) + fprintf(stderr, " -- error expected\n"); + else { + fprintf(stderr, "\n"); + err++; + } + } + else { + if (xpecterr) + err++; + if (!_indom_text) { + fprintf(stderr, "InDomText: %s\n", buf); + _indom_text = 1; + } + free(buf); + } + + if ((n = pmFetch(numpmid, pmidlist, &resp)) < 0) { + fprintf(stderr, "pmFetch: %s", pmErrStr(n)); + if (xpecterr) + fprintf(stderr, " -- error expected\n"); + else { + fprintf(stderr, "\n"); + err++; + } + } + else { + if (xpecterr) + err++; + if (resp->numpmid != numpmid) { + err++; + __pmDumpResult(stderr, resp); + } + else for (j = 0; j < resp->numpmid; j++) { + if (resp->vset[j]->numval < 1) { + err++; + __pmDumpResult(stderr, resp); + break; + } + } + pmFreeResult(resp); + } + + if ((n = pmStore(_store)) < 0) { + fprintf(stderr, "pmStore: %s", pmErrStr(n)); + if (xpecterr) + fprintf(stderr, " -- error expected\n"); + else { + fprintf(stderr, "\n"); + err++; + } + } + else if (xpecterr) + err++; + + if ((n = __pmControlLog(ctlport, _store, PM_LOG_ENQUIRE, 0, 0, &lresp)) < 0) { + fprintf(stderr, "__pmControlLog: %s", pmErrStr(n)); + if (xpecterr) + fprintf(stderr, " -- error expected\n"); + else { + fprintf(stderr, "\n"); + err++; + } + } + else { + pmFreeResult(lresp); + } + + } + if (!xpecterr) + fputc('\n', stderr); + + + return err; +} + +int +main(int argc, char **argv) +{ + int err = 0; + int sts; + int i; + int j; + char *namelist[4]; + pmID pmidlist[4]; + int n; + int numpmid; + int ctx0; + int ctx1; + int c; + int errflag = 0; + char *binadm = pmGetConfig("PCP_BINADM_DIR"); + char path[MAXPATHLEN]; + + __pmSetProgname(argv[0]); + + while ((c = getopt(argc, argv, "D:")) != EOF) { + switch (c) { + case 'D': /* debug flag */ + sts = __pmParseDebug(optarg); + if (sts < 0) { + fprintf(stderr, "%s: unrecognized debug flag specification (%s)\n", + pmProgname, optarg); + errflag++; + } + else + pmDebug |= sts; + break; + + case '?': + default: + errflag++; + break; + } + } + + if (errflag) { + fprintf(stderr, +"Usage: %s options ...\n\ +\n\ +Options:\n\ + -D N set pmDebug debugging flag to N\n", + pmProgname); + exit(1); + } + +#ifndef IS_MINGW + if ((n = geteuid()) != 0) { + fprintf(stderr, "pmcdgone: Must be run as root, not uid %d!\n", n); + exit(1); + } +#endif + + if ((n = pmLoadNameSpace(PM_NS_DEFAULT)) < 0) { + fprintf(stderr, "pmLoadNameSpace: %s\n", pmErrStr(n)); + exit(1); + } + + if ((ctx0 = pmNewContext(PM_CONTEXT_HOST, "localhost")) < 0) { + fprintf(stderr, "pmNewContext: %s\n", pmErrStr(ctx0)); + exit(1); + } + if ((ctx1 = pmNewContext(PM_CONTEXT_HOST, "localhost")) < 0) { + fprintf(stderr, "pmNewContext: %s\n", pmErrStr(ctx1)); + exit(1); + } + _ConnectLogger(); + + i = 0; + namelist[i++] = "sample.long.write_me"; + namelist[i++] = "sample.colour"; + namelist[i++] = "sampledso.bin"; + numpmid = i; + n = pmLookupName(numpmid, namelist, pmidlist); + if (n < 0) { + fprintf(stderr, "pmLookupName: %s\n", pmErrStr(n)); + for (i = 0; i < numpmid; i++) { + if (pmidlist[i] == PM_ID_NULL) + fprintf(stderr, " %s - not known\n", namelist[i]); + } + exit(1); + } + if ((n = pmFetch(1, pmidlist, &_store)) < 0) { + fprintf(stderr, "initial pmFetch failed: %s\n", pmErrStr(n)); + exit(1); + } + if ((n = pmLookupDesc(pmidlist[1], &_desc)) < 0) { + fprintf(stderr, "initial pmLookupDesc failed: %s\n", pmErrStr(n)); + exit(1); + } + if ((_numinst = pmGetInDom(_desc.indom, &_instlist, &_inamelist)) < 0) { + fprintf(stderr, "initial pmGetInDom failed: %s\n", pmErrStr(n)); + exit(1); + } + + err += exer(numpmid, pmidlist, 0); + + fprintf(stderr, "Kill off pmcd ...\n"); + sts = system(". $PCP_DIR/etc/pcp.env; $PCP_RC_DIR/pcp stop"); + if (sts != 0) + fprintf(stderr, "Warning: stop script returns %d\n", sts); + sleep(10); + _text = _indom_text = 0; + __pmCloseSocket(ctlport); + + err += exer(numpmid, pmidlist, 1); + + for (j = 0; j < 2; j++) { + if (j == 0) + i = ctx1; + else + i = ctx0;; + fprintf(stderr, "Reconnect to pmcd context %d ...\n", i); + if ((n = pmReconnectContext(i)) < 0) { + fprintf(stderr, "pmReconnectContext: %s -- error expected\n", pmErrStr(n)); + } + else { + fprintf(stderr, "pmReconnectContext: success after pmcd killed!?\n"); + err++; + } + + err += exer(numpmid, pmidlist, 1); + } + + /* + * tricky part begins ... + * 1. get rid of the archive folio to avoid timestamp clashes with last + * created folio + * 2. re-start pmcd + * 3. wait for pmcd to be accepting connections + * 4. wait for pmlogger to be accepting connections from pmlc + * 5. connect to pmlogger + */ + fprintf(stderr, "Restart pmcd ...\n"); + sts = system(". $PCP_DIR/etc/pcp.env; path_opt=''; if [ $PCP_PLATFORM = linux ]; then path_opt=pmlogger/; fi; pmafm $PCP_LOG_DIR/$path_opt`hostname`/Latest remove 2>/dev/null | sh"); + if (sts != 0) + fprintf(stderr, "Warning: folio removal script %d\n", sts); + __pmCloseSocket(ctlport); + sts = system(". $PCP_DIR/etc/pcp.env; $PCP_RC_DIR/pcp start"); + if (sts != 0) + fprintf(stderr, "Warning: stop script returns %d\n", sts); + + sprintf(path, "%s/pmcd_wait", binadm); + if(access(path, X_OK) == 0) { + sts = system(". $PCP_DIR/etc/pcp.env; [ -x $PCP_BINADM_DIR/pmcd_wait ] && $PCP_BINADM_DIR/pmcd_wait"); + if (sts != 0) + fprintf(stderr, "Warning: pmcd_wait script returns %d\n", sts); + } + + sts = system(". $PCP_DIR/etc/pcp.env; ( cat common.check; echo _wait_for_pmlogger -P $PCP_LOG_DIR/pmlogger/`hostname`/pmlogger.log ) | sh"); + if (sts != 0) + fprintf(stderr, "Warning: _wait_for_pmlogger script returns %d\n", sts); + _ConnectLogger(); + + err += exer(numpmid, pmidlist, 1); + + /* + * more trickery ... + * need to sleep here for at least 1 second so that timestamp of + * IPC failure above is more than 1 second ago, so we wait long enough + * that pmReconnectContext() really does the connect() attempt, rather + * than returning -ETIMEDOUT immediately ... but sleep(1) is unreliable, + * hence ... + */ + sleep(3); + + for (j = 0; j < 2; j++) { + if (j == 0) + i = ctx1; + else + i = ctx0; + fprintf(stderr, "Reconnect to pmcd context %d ...\n", i); + if ((n = pmReconnectContext(i)) < 0) { + fprintf(stderr, "pmReconnectContext: %s\n", pmErrStr(n)); + err++; + } + + err += exer(numpmid, pmidlist, 0); + } + + fprintf(stderr, "%d unexpected errors.\n", err); + exit(0); +} |