#ifndef lint
static char copyright[] =
"@(#) Copyright 2002 Purdue Research Foundation.\nAll rights reserved.\n";
#endif
#include "LsofTest.h"
#include "lsof_fields.h"
#define DO_TEST
#if defined(LT_DIAL_aix)
#undef DO_TEST
#endif
#if defined(LT_DIAL_darwin)
# if LT_VERS<800
#undef DO_TEST
# endif
#endif
#define ATTEMPT_CT 5
#define LSPATH "/bin/ls"
#define SUCCESS_THRESH 50.0
pid_t MyPid = (pid_t)0;
char *Pn = (char *)NULL;
_PROTOTYPE(static void cleanup,(void));
_PROTOTYPE(static char *FindLsofCwd,(int *ff, LTdev_t *cwddc, char *ibuf));
int
main(argc, argv)
int argc;
char *argv[];
{
char buf[2048];
char cwd[MAXPATHLEN + 1];
LTdev_t cwddc;
char *em;
int ff;
int fpathct;
char ibuf[32];
char lsbuf[2048 + MAXPATHLEN + 1];
double pct;
struct stat sb;
int ti;
int xv = 0;
if ((Pn = strrchr(argv[0], '/')))
Pn++;
else
Pn = argv[0];
MyPid = getpid();
(void) printf("%s ... ", Pn);
(void) fflush(stdout);
PrtMsg((char *)NULL, Pn);
if (ScanArg(argc, argv, "h", Pn))
xv = 1;
if (xv || LTopt_h) {
(void) PrtMsg("usage: [-h] [-p path]", Pn);
PrtMsgX(" -h print help (this panel)", Pn, cleanup, xv);
}
#if !defined(DO_TEST)
(void) PrtMsgX(LT_DONT_DO_TEST, Pn, cleanup, 0);
#endif
if ((em = IsLsofExec()))
(void) PrtMsgX(em, Pn, cleanup, 1);
if ((em = CanRdKmem()))
(void) PrtMsgX(em, Pn, cleanup, 1);
#if defined(USE_GETCWD)
em = "getcwd";
if (!getcwd(cwd, sizeof(cwd)))
#else
em = "getwd";
if (!getwd(cwd))
#endif
{
(void) snprintf(buf, sizeof(buf) - 1,
"ERROR!!! %s() error: %s", em, strerror(errno));
buf[sizeof(buf) - 1] = '\0';
(void) PrtMsgX(buf, Pn, cleanup, 1);
}
(void) snprintf(lsbuf, sizeof(lsbuf) - 1, "%s %s > /dev/null 2>&1",
LSPATH, cwd);
if (stat(cwd, &sb)) {
(void) snprintf(buf, sizeof(buf) - 1,
"ERROR!!! stat(%s) error: %s", cwd, strerror(errno));
buf[sizeof(buf) - 1] = '\0';
(void) PrtMsgX(buf, Pn, cleanup, 1);
}
if ((em = ConvStatDev(&sb.st_dev, &cwddc)))
PrtMsgX(em, Pn, cleanup, 1);
(void) snprintf(ibuf, sizeof(ibuf) - 1, "%u", (unsigned int)sb.st_ino);
ibuf[sizeof(ibuf) - 1] = '\0';
for (fpathct = ti = 0; ti < ATTEMPT_CT; ti++) {
(void) system(lsbuf);
if ((em = FindLsofCwd(&ff, &cwddc, ibuf))) {
if (ff == -1)
PrtMsgX(em, Pn, cleanup, 1);
else if (ff == 1) {
PrtMsgX("ERROR!!! inconsistent FindLsofCwd() return", Pn,
cleanup, 1);
}
} else if (ff == 1) {
fpathct++;
}
}
pct = ((double)fpathct * (double)100.0) / (double)ATTEMPT_CT;
PrtMsg((char *)NULL, Pn);
(void) printf("%s found: %.2f%%\n", cwd, pct);
MsgStat = 1;
if (pct < (double)SUCCESS_THRESH) {
PrtMsg("ERROR!!! the find rate was too low.", Pn);
if (!fpathct) {
(void) PrtMsg(
"Hint: since the find rate is zero, it may be that this file",
Pn);
(void) PrtMsg(
"system does not fully participate in kernel DNLC processing",
Pn);
(void) PrtMsg(
"-- e.g., NFS file systems often do not, /tmp file systems",
Pn);
(void) PrtMsg(
"sometimes do not, Solaris loopback file systems do not.\n",
Pn);
(void) PrtMsg(
"As a work-around rebuild and test lsof on a file system that",
Pn);
(void) PrtMsg(
"fully participates in kernel DNLC processing.\n",
Pn);
(void) PrtMsg("See 00FAQ and 00TEST for more information.", Pn);
}
exit(1);
}
(void) PrtMsgX("OK", Pn, cleanup, 0);
return(0);
}
static void
cleanup()
{
}
static char *
FindLsofCwd(ff, cwddc, ibuf)
int *ff;
LTdev_t *cwddc;
char *ibuf;
{
char *cp;
char *cem;
LTfldo_t *cmdp;
LTdev_t devdc;
LTfldo_t *devp;
LTfldo_t *fop;
LTfldo_t *inop;
int nf;
LTfldo_t *nmp;
char *opv[3];
char *pem = (char *)NULL;
pid_t pid;
int pids = 0;
int ti;
LTfldo_t *typ;
if (!ff || !cwddc || !ibuf)
(void) PrtMsgX("ERROR!!! missing argument to FindFile()",
Pn, cleanup, 1);
*ff = 0;
opv[0] = "-clsof";
opv[1] = "-adcwd";
opv[2] = (char *)NULL;
if ((cem = ExecLsof(opv))) {
*ff = -1;
return(cem);
}
while (!*ff && (fop = RdFrLsof(&nf, &cem))) {
if (cem) {
if (pem)
(void) PrtMsg(pem, Pn);
*ff = -1;
return(cem);
}
switch (fop->ft) {
case LSOF_FID_PID:
pid = (pid_t)atoi(fop->v);
pids = 1;
cmdp = (LTfldo_t *)NULL;
for (fop++, ti = 1; ti < nf; fop++, ti++) {
switch (fop->ft) {
case LSOF_FID_CMD:
cmdp = fop;
break;
}
}
if (!cmdp || (pid != LsofPid))
pids = 0;
break;
case LSOF_FID_FD:
if (!pids)
break;
if (strcasecmp(fop->v, "cwd"))
break;
devp = inop = nmp = typ = (LTfldo_t *)NULL;
for (fop++, ti = 1; ti < nf; fop++, ti++) {
switch (fop->ft) {
case LSOF_FID_DEVN:
devp = fop;
break;
case LSOF_FID_INODE:
inop = fop;
break;
case LSOF_FID_NAME:
nmp = fop;
break;
case LSOF_FID_TYPE:
typ = fop;
break;
}
}
if (!devp || !inop || !nmp || !typ)
break;
if (strcasecmp(typ->v, "dir") && strcasecmp(typ->v, "vdir"))
break;
if ((cem = ConvLsofDev(devp->v, &devdc))) {
if (pem)
(void) PrtMsg(pem, Pn);
pem = cem;
break;
}
if ((cwddc->maj != devdc.maj)
|| (cwddc->min != devdc.min)
|| (cwddc->unit != devdc.unit)
|| strcmp(inop->v, ibuf)
) {
break;
}
if (!(cp = strchr(nmp->v, ' ')))
*ff = 1;
else {
if ((*(cp + 1) == '(') && *(cp + 2) && !strchr(cp + 2, ' ')) {
if ((cp = strchr(cp + 2, ')')) && !*(cp + 1))
*ff = 1;
}
}
}
}
(void) StopLsof();
if (pem) {
*ff = -1;
return(pem);
}
return((char *)NULL);
}