int main(int argc, char *argv[]) { int c; int sts; int ctx; int i; int lflag = 0; /* no label by default */ int nfile; int n; char *p; struct dirent **namelist; __pmContext *ctxp; char *archpathname; /* from the command line */ char *archdirname; /* after dirname() */ char archname[MAXPATHLEN]; /* full pathname to base of archive name */ while ((c = pmGetOptions(argc, argv, &opts)) != EOF) { switch (c) { case 'l': /* display the archive label */ lflag = 1; break; case 'v': /* bump verbosity */ vflag++; break; } } if (!opts.errors && opts.optind >= argc) { pmprintf("Error: no archive specified\n\n"); opts.errors++; } if (opts.errors) { pmUsageMessage(&opts); exit(EXIT_FAILURE); } sep = __pmPathSeparator(); setlinebuf(stderr); __pmAddOptArchive(&opts, argv[opts.optind]); opts.flags &= ~PM_OPTFLAG_DONE; __pmEndOptions(&opts); archpathname = argv[opts.optind]; archbasename = strdup(basename(strdup(archpathname))); /* * treat foo, foo.index, foo.meta, foo.NNN as all equivalent * to "foo" */ p = strrchr(archbasename, '.'); if (p != NULL) { if (strcmp(p, ".index") == 0 || strcmp(p, ".meta") == 0) *p = '\0'; else { char *q = p; q++; if (isdigit(*q)) { /* * foo.<digit> ... if archpathname does exist, then * safe to strip digits, else leave as is for the * case of, e.g. archive-20150415.041154 which is the * pmmgr basename for an archive with a first volume * named archive-20150415.041154.0 */ if (access(archpathname, F_OK) == 0) { q++; while (*q && isdigit(*q)) q++; if (*q == '\0') *p = '\0'; } } } } archdirname = dirname(strdup(archpathname)); if (vflag) fprintf(stderr, "Scanning for components of archive \"%s\"\n", archpathname); nfile = scandir(archdirname, &namelist, filter, NULL); if (nfile < 1) { fprintf(stderr, "%s: no PCP archive files match \"%s\"\n", pmProgname, archpathname); exit(EXIT_FAILURE); } /* * Pass 0 for data, metadata and index files ... check physical * archive record structure, then label record */ sts = STS_OK; for (i = 0; i < nfile; i++) { char path[MAXPATHLEN]; if (strcmp(archdirname, ".") == 0) { /* skip ./ prefix */ strncpy(path, namelist[i]->d_name, sizeof(path)); } else { snprintf(path, sizeof(path), "%s%c%s", archdirname, sep, namelist[i]->d_name); } if (pass0(path) == STS_FATAL) /* unrepairable or unrepaired error */ sts = STS_FATAL; } if (meta_state == STATE_MISSING) { fprintf(stderr, "%s%c%s.meta: missing metadata file\n", archdirname, sep, archbasename); sts = STS_FATAL; } if (log_state == STATE_MISSING) { fprintf(stderr, "%s%c%s.0 (or similar): missing log file \n", archdirname, sep, archbasename); sts = STS_FATAL; } if (sts == STS_FATAL) { if (vflag) fprintf(stderr, "Due to earlier errors, cannot continue ... bye\n"); exit(EXIT_FAILURE); } if ((sts = ctx = pmNewContext(PM_CONTEXT_ARCHIVE, archpathname)) < 0) { fprintf(stderr, "%s: cannot open archive \"%s\": %s\n", pmProgname, archpathname, pmErrStr(sts)); fprintf(stderr, "Checking abandoned.\n"); exit(EXIT_FAILURE); } if (pmGetContextOptions(ctx, &opts) < 0) { pmflush(); /* runtime errors only at this stage */ exit(EXIT_FAILURE); } if (lflag) dumpLabel(); /* * Note: ctxp->c_lock remains locked throughout ... __pmHandleToPtr() * is only called once, and a single context is used throughout * ... so there is no PM_UNLOCK(ctxp->c_lock) anywhere in the * pmchecklog code. * This works because ctxp->c_lock is a recursive lock and * pmchecklog is single-threaded. */ if ((n = pmWhichContext()) >= 0) { if ((ctxp = __pmHandleToPtr(n)) == NULL) { fprintf(stderr, "%s: botch: __pmHandleToPtr(%d) returns NULL!\n", pmProgname, n); exit(EXIT_FAILURE); } } else { fprintf(stderr, "%s: botch: %s!\n", pmProgname, pmErrStr(PM_ERR_NOCONTEXT)); exit(EXIT_FAILURE); } if (strcmp(archdirname, ".") == 0) /* skip ./ prefix */ strncpy(archname, archbasename, sizeof(archname) - 1); else snprintf(archname, sizeof(archname), "%s%c%s", archdirname, sep, archbasename); sts = pass1(ctxp, archname); if (index_state == STATE_BAD) { /* prevent subsequent use of bad temporal index */ ctxp->c_archctl->ac_log->l_numti = 0; } sts = pass2(ctxp, archname); sts = pass3(ctxp, archname, &opts); if (vflag) { if (result_count > 0) fprintf(stderr, "Processed %d pmResult records\n", result_count); if (mark_count > 0) fprintf(stderr, "Processed %d <mark> records\n", mark_count); } return 0; }
int main(int argc, char *argv[]) { int c; int sts; char *rawfile = NULL; int i; int ctxid; int first = 1; int dflag = 0; int iflag = 0; int Lflag = 0; int lflag = 0; int Mflag = 0; int mflag = 0; int tflag = 0; int vflag = 0; int mode = PM_MODE_FORW; __pmContext *ctxp; pmResult *raw_result; pmResult *skel_result = NULL; pmResult *result; struct timeval done; while ((c = pmGetOptions(argc, argv, &opts)) != EOF) { switch (c) { case 'a': /* dump everything */ dflag = iflag = lflag = mflag = sflag = tflag = 1; break; case 'd': /* dump pmDesc structures */ dflag = 1; break; case 'i': /* dump instance domains */ iflag = 1; break; case 'L': /* dump label, verbose */ Lflag = 1; lflag = 1; break; case 'l': /* dump label */ lflag = 1; break; case 'm': /* dump metrics in log */ mflag = 1; break; case 'M': /* report <mark> records */ Mflag = 1; break; case 'r': /* read log in reverse chornological order */ mode = PM_MODE_BACK; break; case 's': /* report data size in log */ sflag = 1; break; case 't': /* dump temporal index */ tflag = 1; break; case 'v': /* verbose, dump in raw format */ vflag = 1; rawfile = opts.optarg; break; case 'x': /* report Ddd Mmm DD <timestamp> YYYY */ /* -xx reports numeric timeval also */ xflag++; break; } } if (opts.errors || (vflag && opts.optind != argc) || (!vflag && opts.optind > argc - 1 && !opts.narchives)) { pmUsageMessage(&opts); exit(1); } if (vflag) { FILE *f; if ((f = fopen(rawfile, "r")) == NULL) { fprintf(stderr, "%s: Cannot open \"%s\": %s\n", pmProgname, rawfile, osstrerror()); exit(1); } printf("Raw dump of physical archive file \"%s\" ...\n", rawfile); rawdump(f); exit(0); } if (dflag + iflag + lflag + mflag + tflag == 0) mflag = 1; /* default */ /* delay option end processing until now that we have the archive name */ if (opts.narchives == 0) __pmAddOptArchive(&opts, argv[opts.optind++]); opts.flags &= ~PM_OPTFLAG_DONE; __pmEndOptions(&opts); if ((sts = ctxid = pmNewContext(PM_CONTEXT_ARCHIVE, opts.archives[0])) < 0) { fprintf(stderr, "%s: Cannot open archive \"%s\": %s\n", pmProgname, opts.archives[0], pmErrStr(sts)); exit(1); } /* complete TZ and time window option (origin) setup */ if (pmGetContextOptions(ctxid, &opts)) { pmflush(); exit(1); } numpmid = argc - opts.optind; if (numpmid) { numpmid = 0; pmid = NULL; for (i = 0; opts.optind < argc; i++, opts.optind++) { numpmid++; pmid = (pmID *)realloc(pmid, numpmid * sizeof(pmID)); if ((sts = pmLookupName(1, &argv[opts.optind], &pmid[numpmid-1])) < 0) { if (sts == PM_ERR_NONLEAF) { numpmid--; if ((sts = pmTraversePMNS(argv[opts.optind], dometric)) < 0) fprintf(stderr, "%s: pmTraversePMNS(%s): %s\n", pmProgname, argv[opts.optind], pmErrStr(sts)); } else fprintf(stderr, "%s: pmLookupName(%s): %s\n", pmProgname, argv[opts.optind], pmErrStr(sts)); if (sts < 0) numpmid--; } } if (numpmid == 0) { fprintf(stderr, "No metric names can be translated, dump abandoned\n"); exit(1); } } if ((sts = pmGetArchiveLabel(&label)) < 0) { fprintf(stderr, "%s: Cannot get archive label record: %s\n", pmProgname, pmErrStr(sts)); exit(1); } if (numpmid > 0) { /* * setup dummy pmResult */ skel_result = (pmResult *)malloc(sizeof(pmResult)+(numpmid-1)*sizeof(pmValueSet *)); if (skel_result == NULL) { fprintf(stderr, "%s: malloc(skel_result): %s\n", pmProgname, osstrerror()); exit(1); } } /* * Note: ctxp->c_lock remains locked throughout ... __pmHandleToPtr() * is only called once, and a single context is used throughout * ... so there is no PM_UNLOCK(ctxp->c_lock) anywhere in the * pmdumplog code. * This works because ctxp->c_lock is a recursive lock and * pmdumplog is single-threaded. */ if ((ctxp = __pmHandleToPtr(ctxid)) == NULL) { fprintf(stderr, "%s: botch: __pmHandleToPtr(%d) returns NULL!\n", pmProgname, ctxid); exit(1); } pmSetMode(mode, &opts.start, 0); if (lflag) dumpLabel(Lflag); if (dflag) dumpDesc(ctxp); if (iflag) dumpInDom(ctxp); if (tflag) dumpTI(ctxp); if (mflag) { if (mode == PM_MODE_FORW) { if (opts.start_optarg != NULL || opts.finish_optarg != NULL) { /* -S or -T */ sts = pmSetMode(mode, &opts.start, 0); done = opts.finish; } else { /* read the whole archive */ done.tv_sec = 0; done.tv_usec = 0; sts = pmSetMode(mode, &done, 0); done.tv_sec = INT_MAX; } } else { if (opts.start_optarg != NULL || opts.finish_optarg != NULL) { /* -S or -T */ done.tv_sec = INT_MAX; done.tv_usec = 0; sts = pmSetMode(mode, &done, 0); done = opts.start; } else { /* read the whole archive backwards */ done.tv_sec = INT_MAX; done.tv_usec = 0; sts = pmSetMode(mode, &done, 0); done.tv_sec = 0; } } if (sts < 0) { fprintf(stderr, "%s: pmSetMode: %s\n", pmProgname, pmErrStr(sts)); exit(1); } sts = 0; for ( ; ; ) { sts = __pmLogFetch(ctxp, 0, NULL, &raw_result); if (sts < 0) break; if (numpmid == 0 || (raw_result->numpmid == 0 && Mflag)) { /* * want 'em all or <mark> record ... */ result = raw_result; } else if (numpmid > 0) { /* * cherry pick from raw_result if pmid matches one * of interest */ int picked = 0; int j; skel_result->timestamp = raw_result->timestamp; for (j = 0; j < numpmid; j++) skel_result->vset[j] = NULL; for (i = 0; i < raw_result->numpmid; i++) { for (j = 0; j < numpmid; j++) { if (pmid[j] == raw_result->vset[i]->pmid) { skel_result->vset[j] = raw_result->vset[i]; picked++; break; } } } if (picked == 0) { /* no metrics of interest, skip this record */ pmFreeResult(raw_result); continue; } skel_result->numpmid = picked; if (picked != numpmid) { /* did not find 'em all ... shuffle time */ int j; i = 0; for (j = 0; j < numpmid; j++) { if (skel_result->vset[j] != NULL) skel_result->vset[i++] = skel_result->vset[j]; } } result = skel_result; } else { /* not interesting */ pmFreeResult(raw_result); continue; } if (first && mode == PM_MODE_BACK) { first = 0; printf("\nLog finished at %24.24s - dump in reverse order\n", pmCtime(&result->timestamp.tv_sec, timebuf)); } if ((mode == PM_MODE_FORW && tvcmp(result->timestamp, done) > 0) || (mode == PM_MODE_BACK && tvcmp(result->timestamp, done) < 0)) { sts = PM_ERR_EOL; break; } putchar('\n'); dump_result(result); pmFreeResult(raw_result); } if (sts != PM_ERR_EOL) { fprintf(stderr, "%s: pmFetch: %s\n", pmProgname, pmErrStr(sts)); exit(1); } } exit(0); }
int main(int argc, char *argv[]) { register int i; int c; char *p; char path[MAXPATHLEN]; pmOptions opts = { .short_options = allflags, .flags = PM_OPTFLAG_BOUNDARIES, }; /* ** preserve command arguments to allow restart of other version */ argvp = argv; /* ** read defaults-files /etc/atoprc en $HOME/.atoprc (if any) */ readrc("/etc/atoprc", 1); if ( (p = getenv("HOME")) ) { snprintf(path, sizeof(path), "%s/.atoprc", p); path[sizeof(path)-1] = '\0'; readrc(path, 0); } /* ** check if we are supposed to behave as 'atopsar' ** i.e. system statistics only */ __pmSetProgname(argv[0]); if (strcmp(pmProgname, "pcp-atopsar") == 0) return atopsar(argc, argv); __pmStartOptions(&opts); if (opts.narchives > 0) rawreadflag++; /* ** interpret command-line arguments & flags */ if (argc > 1) { /* ** gather all flags for visualization-functions ** ** generic flags will be handled here; ** unrecognized flags are passed to the print-routines */ i = 0; while (i < MAXFL-1 && (c = pmgetopt_r(argc, argv, &opts)) != EOF) { switch (c) { case '?': /* usage wanted ? */ prusage(pmProgname); break; case 'V': /* version wanted ? */ printf("%s\n", getstrvers()); exit(0); case 'w': /* writing of raw data ? */ rawname = opts.optarg; rawwriteflag++; break; case 'r': /* reading of raw data ? */ rawarchive(&opts, opts.optarg); rawreadflag++; break; case 'S': /* midnight limit ? */ midnightflag++; break; case 'a': /* all processes per sample ? */ deviatonly = 0; break; case 'R': /* all processes per sample ? */ calcpss = 1; break; case 'b': /* begin time ? */ opts.start_optarg = abstime(opts.optarg); break; case 'e': /* end time ? */ opts.finish_optarg = abstime(opts.optarg); break; case 'P': /* parseable output? */ if ( !parsedef(opts.optarg) ) prusage(pmProgname); vis.show_samp = parseout; break; case 'L': /* line length */ if ( !numeric(opts.optarg) ) prusage(pmProgname); linelen = atoi(opts.optarg); break; default: /* gather other flags */ flaglist[i++] = c; } } /* ** get optional interval-value and optional number of samples */ if (opts.optind < argc && opts.optind < MAXFL) { char *endnum, *arg; arg = argv[opts.optind++]; if (pmParseInterval(arg, &opts.interval, &endnum) < 0) { pmprintf( "%s: %s option not in pmParseInterval(3) format:\n%s\n", pmProgname, arg, endnum); free(endnum); opts.errors++; } else interval = opts.interval; if (opts.optind < argc) { arg = argv[opts.optind]; if (!numeric(arg)) prusage(pmProgname); if ((opts.samples = atoi(arg)) < 1) prusage(pmProgname); nsamples = opts.samples; } } } __pmEndOptions(&opts); if (opts.errors) prusage(pmProgname); /* ** find local host details (no privileged access required) */ setup_globals(&opts); /* ** check if we are in data recording mode */ if (rawwriteflag) { rawwrite(&opts, rawname, &interval, nsamples, midnightflag); cleanstop(0); } /* ** catch signals for proper close-down */ signal(SIGHUP, cleanstop); signal(SIGTERM, cleanstop); /* ** switch-on the process-accounting mechanism to register the ** (remaining) resource-usage by processes which have finished */ acctreason = acctswon(); /* ** determine properties (like speed) of all interfaces */ initifprop(); /* ** open socket to the IP layer to issue getsockopt() calls later on */ netatop_ipopen(); /* ** start the engine now ..... */ engine(); cleanstop(0); return 0; /* never reached */ }