From: fsgqa Date: Wed, 3 Sep 2003 00:30:33 +0000 (+0000) Subject: Make test 040 less verbose since only I need to know this; integrate some old IRIX... X-Git-Tag: v1.1.0~927 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=7964cf8496f1811caa9c1a532e0068f29b0322a3;p=xfstests-dev.git Make test 040 less verbose since only I need to know this; integrate some old IRIX performance unit tests - metaperf and dirperf --- diff --git a/040 b/040 index b865b915..57f67306 100755 --- a/040 +++ b/040 @@ -36,7 +36,7 @@ #----------------------------------------------------------------------- # # creator -owner=dxm@sgi.com +owner=nathans@sgi.com seq=`basename $0` echo "QA output created by $seq" @@ -74,8 +74,13 @@ then _notrun "Can't find XFS command headers under \"$WORKAREA\"" fi -cd $WORKAREA/cmd/xfstests/tools -perl ./srcdiff -q +cd $WORKAREA/cmd/xfstests +echo Silence is golden. +perl tools/srcdiff -q >$seq.full +if ! diff $seq.full $seq.good >/dev/null; then + echo "FAILED: srcdiff output $seq.full differs to $seq.good" + exit 1 +fi # success, all done status=0 diff --git a/040.good b/040.good new file mode 100644 index 00000000..6df7788e --- /dev/null +++ b/040.good @@ -0,0 +1,16 @@ + +=== Checking attr package === + +=== Checking acl package === + +=== Checking dmapi package === + +=== Checking xfsdump package === + +=== Checking xfsprogs package === + +=== Checking headers === + +=== Checking libxfs code === + +=== Checking libxlog code === diff --git a/040.out b/040.out index f4e671f8..45b1dea5 100644 --- a/040.out +++ b/040.out @@ -1,17 +1,2 @@ QA output created by 040 - -=== Checking attr package === - -=== Checking acl package === - -=== Checking dmapi package === - -=== Checking xfsdump package === - -=== Checking xfsprogs package === - -=== Checking headers === - -=== Checking libxfs code === - -=== Checking libxlog code === +Silence is golden. diff --git a/src/Makefile b/src/Makefile index 8488efeb..daa1f736 100644 --- a/src/Makefile +++ b/src/Makefile @@ -36,7 +36,8 @@ include $(TOPDIR)/include/builddefs TARGETS = alloc acl_get bstat devzero dirstress fault feature \ fill fill2 getpagesize holes xfsctl loggen lstat64 \ nametest permname randholes runas truncfile usemem \ - fstest mmapcat append_reader append_writer + fstest mmapcat append_reader append_writer \ + dirperf metaperf ifeq ($(ENABLE_DBM), yes) TARGETS += dbtest endif @@ -67,5 +68,8 @@ bstat: bstat.o $(LIBHANDLE) loggen: loggen.o $(LINKTEST) $(LDLIBS) +fstest: fstest.o + $(LINKTEST) + acl_get: acl_get.o $(LIBACL) $(LIBATTR) $(LINKTEST) $(LIBACL) $(LIBATTR) $(LDLIBS) diff --git a/src/dirperf.c b/src/dirperf.c new file mode 100644 index 00000000..d1159f29 --- /dev/null +++ b/src/dirperf.c @@ -0,0 +1,286 @@ +/* + * Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * Further, this software is distributed without any warranty that it is + * free of the rightful claim of any third person regarding infringement + * or the like. Any license provided herein, whether implied or + * otherwise, applies only to this software file. Patent licenses, if + * any, provided herein do not apply to combinations of this program with + * other software, or any other product whatsoever. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, + * Mountain View, CA 94043, or: + * + * http://www.sgi.com + * + * For further information regarding this notice, see: + * + * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MAXNAMELEN 256 +typedef unsigned int uint_t; + +/* + * Loop over directory sizes: + * make m directories + * touch n files in each directory + * stat the files round-robin + * readdir/unlink the files + * Change directory sizes by multiplication or addition. + * Allow control of starting & stopping sizes, name length, target directory. + * Print size and wallclock time (ms per file). + * Output can be used to make graphs (gnuplot) + */ + +static uint_t addval; +static uint_t dirchars; +static char *dirname; +static uint_t firstsize; +static uint_t lastsize; +static uint_t minchars; +static double mulval; +static uint_t nchars; +static uint_t ndirs; +static uint_t pfxchars; +static uint_t stats; + +static void filename(int, int, char *); +static int hexchars(uint_t); +static uint_t nextsize(uint_t); +static double now(void); +static void usage(void); + +/* + * Maximum size allowed, this is pretty nuts. + * The largest one we've ever built has been about 2 million. + */ +#define MAX_DIR_SIZE (16 * 1024 * 1024) +#define DFL_FIRST_SIZE 1 +#define DFL_LAST_SIZE (1024 * 1024) +#define MAX_DIR_COUNT 1024 + +int +main(int argc, char **argv) +{ + int c; + uint_t cursize; + DIR *dirp; + int i; + int j; + char name[MAXNAMELEN]; + struct stat stb; + double stime; + + while ((c = getopt(argc, argv, "a:c:d:f:l:m:n:s:")) != -1) { + switch (c) { + case 'a': + addval = (uint_t)atoi(optarg); + break; + case 'c': + nchars = (uint_t)atoi(optarg); + break; + case 'd': + dirname = optarg; + break; + case 'f': + firstsize = (uint_t)atoi(optarg); + break; + case 'l': + lastsize = (uint_t)atoi(optarg); + break; + case 'm': + mulval = atof(optarg); + break; + case 'n': + ndirs = (uint_t)atoi(optarg); + break; + case 's': + stats = (uint_t)atoi(optarg); + break; + case '?': + default: + usage(); + exit(1); + } + } + if (!addval && !mulval) + mulval = 2.0; + else if ((addval && mulval) || mulval < 0.0) { + usage(); + exit(1); + } + if (stats == 0) + stats = 1; + if (!dirname) + dirname = "."; + else { + if (mkdir(dirname, 0777) < 0 && errno != EEXIST) { + perror(dirname); + exit(1); + } + if (chdir(dirname) < 0) { + perror(dirname); + exit(1); + } + } + if (firstsize == 0) + firstsize = DFL_FIRST_SIZE; + else if (firstsize > MAX_DIR_SIZE) + firstsize = MAX_DIR_SIZE; + if (lastsize == 0) + lastsize = DFL_LAST_SIZE; + else if (lastsize > MAX_DIR_SIZE) + lastsize = MAX_DIR_SIZE; + if (lastsize < firstsize) + lastsize = firstsize; + minchars = hexchars(lastsize - 1); + if (nchars < minchars) + nchars = minchars; + else if (nchars >= MAXNAMELEN) + nchars = MAXNAMELEN - 1; + if (ndirs > MAX_DIR_COUNT) + ndirs = MAX_DIR_COUNT; + dirchars = hexchars(ndirs); + pfxchars = nchars - minchars; + if (pfxchars) + memset(&name[dirchars + 1], 'a', pfxchars); + for (j = 0; j < ndirs; j++) { + filename(0, j, name); + name[dirchars] = '\0'; + mkdir(name, 0777); + } + for (cursize = firstsize; + cursize <= lastsize; + cursize = nextsize(cursize)) { + stime = now(); + for (i = 0; i < cursize; i++) { + for (j = 0; j < ndirs; j++) { + filename((i + j) % cursize, j, name); + close(creat(name, 0666)); + } + } + for (i = 0; i < cursize * stats; i++) { + for (j = 0; j < ndirs; j++) { + filename((i + j) % cursize, j, name); + stat(name, &stb); + } + } + for (j = 0; j < ndirs; j++) { + filename(0, j, name); + name[dirchars] = '\0'; + dirp = opendir(name); + while (readdir(dirp)) + continue; + closedir(dirp); + } + for (i = 0; i < cursize; i++) { + for (j = 0; j < ndirs; j++) { + filename((i + j) % cursize, j, name); + unlink(name); + } + } + printf("%d %.3f\n", cursize, + (now() - stime) * 1.0e3 / (cursize * ndirs)); + } + for (j = 0; j < ndirs; j++) { + filename(0, j, name); + name[dirchars] = '\0'; + rmdir(name); + } + return 0; +} + +static void +filename(int idx, int dir, char *name) +{ + static char hexc[16] = "0123456789abcdef"; + int i; + + for (i = dirchars - 1; i >= 0; i--) + *name++ = hexc[(dir >> (4 * i)) & 0xf]; + *name++ = '/'; + name += pfxchars; /* skip pfx a's */ + for (i = minchars - 1; i >= 0; i--) + *name++ = hexc[(idx >> (4 * i)) & 0xf]; + *name = '\0'; +} + +static int +hexchars(uint_t maxval) +{ + if (maxval < 16) + return 1; + if (maxval < 16 * 16) + return 2; + if (maxval < 16 * 16 * 16) + return 3; + if (maxval < 16 * 16 * 16 * 16) + return 4; + if (maxval < 16 * 16 * 16 * 16 * 16) + return 5; + if (maxval < 16 * 16 * 16 * 16 * 16 * 16) + return 6; + if (maxval < 16 * 16 * 16 * 16 * 16 * 16 * 16) + return 7; + return 8; +} + +static uint_t +nextsize(uint_t cursize) +{ + double n; + + n = cursize; + if (addval) + n += addval; + else + n *= mulval; + if (n > (double)lastsize + 0.5) + return lastsize + 1; /* i.e. out of bounds */ + else if ((uint_t)n == cursize) + return cursize + 1; + else + return (uint_t)n; +} + +static double +now(void) +{ + struct timeval tv; + + gettimeofday(&tv, NULL); + return (double)tv.tv_sec + 1.0e-6 * (double)tv.tv_usec; +} + +static void +usage(void) +{ + fprintf(stderr, + "usage: dirperf [-d dir] [-a addstep | -m mulstep] [-f first] " + "[-l last] [-c nchars] [-n ndirs] [-s nstats]\n"); +} diff --git a/src/metaperf.c b/src/metaperf.c new file mode 100644 index 00000000..f4d7eafb --- /dev/null +++ b/src/metaperf.c @@ -0,0 +1,574 @@ +/* + * Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * Further, this software is distributed without any warranty that it is + * free of the rightful claim of any third person regarding infringement + * or the like. Any license provided herein, whether implied or + * otherwise, applies only to this software file. Patent licenses, if + * any, provided herein do not apply to combinations of this program with + * other software, or any other product whatsoever. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, + * Mountain View, CA 94043, or: + * + * http://www.sgi.com + * + * For further information regarding this notice, see: + * + * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef HAVE_GETDENTS +#include +#endif + +typedef void *(*fpi_t)(void); +typedef void (*fpt_t)(int, void *); +typedef void (*fpd_t)(void *); +typedef struct tdesc +{ + char *name; + fpi_t init; + fpt_t test; + fpd_t done; +} tdesc_t; + +#ifdef HAVE_GETDENTS +static void d_getdents(void *); +static void *i_getdents(void); +static void t_getdents(int, void *); +#endif +static void crfiles(char **, int, char *); +static void d_chown(void *); +static void d_create(void *); +static void d_linkun(void *); +static void d_open(void *); +static void d_rename(void *); +static void d_stat(void *); +static void delflist(char **); +static void dotest(tdesc_t *); +static void *i_chown(void); +static void *i_create(void); +static void *i_linkun(void); +static void *i_open(void); +static void *i_rename(void); +static void *i_stat(void); +static char **mkflist(int, int, char); +static double now(void); +static void prtime(char *, int, double); +static void rmfiles(char **); +static void t_chown(int, void *); +static void t_create(int, void *); +static void t_crunlink(int, void *); +static void t_linkun(int, void *); +static void t_open(int, void *); +static void t_rename(int, void *); +static void t_stat(int, void *); +static void usage(void); + +tdesc_t tests[] = { + { "chown", i_chown, t_chown, d_chown }, + { "create", i_create, t_create, d_create }, + { "crunlink", (fpi_t)0, t_crunlink, (fpd_t)0 }, +#ifdef HAVE_GETDENTS + { "getdents", i_getdents, t_getdents, d_getdents }, +#endif + { "linkun", i_linkun, t_linkun, d_linkun }, + { "open", i_open, t_open, d_open }, + { "rename", i_rename, t_rename, d_rename }, + { "stat", i_stat, t_stat, d_stat }, + { NULL } +}; + +char *buffer; +int compact = 0; +int files_bg = 0; +int files_op = 1; +char **flist_bg; +char **flist_op; +int fnlen_bg = 5; +int fnlen_op = 5; +int fsize = 0; +int iters = 0; +double time_end; +double time_start; +int totsec = 0; +int verbose = 0; + +struct getdents_data +{ + void *buffer; + int buflen; + int fd; +}; + +int +main(int argc, char **argv) +{ + int c; + char *testdir; + tdesc_t *tp; + + testdir = getenv("TMPDIR"); + if (testdir == NULL) + testdir = "."; + while ((c = getopt(argc, argv, "cd:i:l:L:n:N:s:t:v")) != -1) { + switch (c) { + case 'c': + compact = 1; + break; + case 'd': + testdir = optarg; + break; + case 'i': + iters = atoi(optarg); + break; + case 'l': + fnlen_op = atoi(optarg); + break; + case 'L': + fnlen_bg = atoi(optarg); + break; + case 'n': + files_op = atoi(optarg); + break; + case 'N': + files_bg = atoi(optarg); + break; + case 's': + fsize = atoi(optarg); + break; + case 't': + totsec = atoi(optarg); + break; + case 'v': + verbose = 1; + break; + case '?': + fprintf(stderr, "bad option\n"); + usage(); + } + } + if (!iters && !totsec) + iters = 1; + if (chdir(testdir) < 0) { + perror(testdir); + return 1; + } + if (mkdir("metaperf", 0777) < 0 || chdir("metaperf") < 0) { + perror("metaperf"); + return 1; + } + for (; optind < argc; optind++) { + for (tp = tests; tp->name; tp++) { + if (strcmp(argv[optind], tp->name) == 0) { + dotest(tp); + break; + } + } + } + chdir(".."); + rmdir("metaperf"); + return 0; +} + +static void +crfiles(char **flist, int fsize, char *buf) +{ + int fd; + char **fnp; + + for (fnp = flist; *fnp; fnp++) { + fd = creat(*fnp, 0666); + if (fsize) + write(fd, buf, fsize); + close(fd); + } +} + +/* ARGSUSED */ +static void +d_chown(void *v) +{ + rmfiles(flist_op); +} + +/* ARGSUSED */ +static void +d_create(void *v) +{ + rmfiles(flist_op); +} + +#ifdef HAVE_GETDENTS +static void +d_getdents(void *v) +{ + struct getdents_data *g; + + rmfiles(flist_op); + g = v; + close(g->fd); + free(g->buffer); + free(g); +} +#endif + +/* ARGSUSED */ +static void +d_linkun(void *v) +{ + unlink("a"); +} + +/* ARGSUSED */ +static void +d_open(void *v) +{ + rmfiles(flist_op); +} + +static void +d_rename(void *v) +{ + rmfiles(flist_op); + rmfiles((char **)v); + delflist((char **)v); +} + +/* ARGSUSED */ +static void +d_stat(void *v) +{ + rmfiles(flist_op); +} + +static void +delflist(char **flist) +{ + char **fnp; + + for (fnp = flist; *fnp; fnp++) + free(*fnp); + free(flist); +} + +static void +dotest(tdesc_t *tp) +{ + double dn; + double gotsec; + int n; + void *v; + + flist_bg = mkflist(files_bg, fnlen_bg, 'b'); + flist_op = mkflist(files_op, fnlen_op, 'o'); + if (fsize) + buffer = calloc(fsize, 1); + else + buffer = NULL; + crfiles(flist_bg, 0, (char *)0); + n = iters ? iters : 1; + v = (void *)0; + for (;;) { + if (tp->init) + v = (tp->init)(); + sync(); + sleep(1); + time_start = now(); + (tp->test)(n, v); + time_end = now(); + if (tp->done) + (tp->done)(v); + gotsec = time_end - time_start; + if (!totsec || gotsec >= 0.9 * totsec) + break; + if (verbose) + prtime(tp->name, n, gotsec); + if (!gotsec) + gotsec = 1.0 / (2 * HZ); + if (gotsec < 0.001 * totsec) + dn = n * (0.01 * totsec / gotsec); + else if (gotsec < 0.01 * totsec) + dn = n * (0.1 * totsec / gotsec); + else + dn = n * (totsec / gotsec); + if ((int)dn <= n) + n++; + else + n = (int)dn; + } + prtime(tp->name, n, gotsec); + rmfiles(flist_bg); + delflist(flist_bg); + delflist(flist_op); + if (fsize) + free(buffer); +} + +static void * +i_chown(void) +{ + char **fnp; + + crfiles(flist_op, 0, (char *)0); + for (fnp = flist_op; *fnp; fnp++) + chown(*fnp, 1, -1); + return (void *)0; +} + +static void * +i_create(void) +{ + crfiles(flist_op, fsize, buffer); + return (void *)0; +} + +#ifdef HAVE_GETDENTS +static void * +i_getdents(void) +{ + struct getdents_data *g; + + crfiles(flist_op, 0, (char *)0); + g = malloc(sizeof(*g)); + g->buflen = 16 * 1024; + g->buffer = malloc(g->buflen); + g->fd = open(".", O_RDONLY); + return g; +} +#endif + +static void * +i_linkun(void) +{ + close(creat("a", 0666)); + return (void *)0; +} + +static void * +i_open(void) +{ + crfiles(flist_op, 0, (char *)0); + return (void *)0; +} + +static void * +i_rename(void) +{ + crfiles(flist_op, 0, (char *)0); + return (void *)mkflist(files_op, fnlen_op, 'r'); +} + +static void * +i_stat(void) +{ + crfiles(flist_op, 0, (char *)0); + return (void *)0; +} + +static char ** +mkflist(int files, int fnlen, char start) +{ + int i; + char **rval; + + rval = calloc(files + 1, sizeof(char *)); + for (i = 0; i < files; i++) { + rval[i] = malloc(fnlen + 1); + sprintf(rval[i], "%0*d%c", fnlen - 1, i, start); + } + return rval; +} + +static double +now(void) +{ + struct timeval t; + + gettimeofday(&t, (void *)0); + return (double)t.tv_sec + 1.0e-6 * (double)t.tv_usec; +} + +static void +prtime(char *name, int n, double t) +{ + double ops_per_sec; + double usec_per_op; + + ops_per_sec = (double)n * (double)files_op / t; + usec_per_op = t * 1.0e6 / ((double)n * (double)files_op); + if (compact) + printf("%s %d %d %d %d %d %d %f %f %f\n", + name, n, files_op, fnlen_op, fsize, files_bg, fnlen_bg, + t, ops_per_sec, usec_per_op); + else { + printf("%s: %d times, %d file(s) namelen %d", + name, n, files_op, fnlen_op); + if (fsize) + printf(" size %d", fsize); + if (files_bg) + printf(", bg %d file(s) namelen %d", + files_bg, fnlen_bg); + printf(", time = %f sec, ops/sec=%f, usec/op = %f\n", + t, ops_per_sec, usec_per_op); + } +} + +static void +rmfiles(char **flist) +{ + char **fnp; + + for (fnp = flist; *fnp; fnp++) + unlink(*fnp); +} + +/* ARGSUSED */ +static void +t_chown(int n, void *v) +{ + char **fnp; + int i; + + for (i = 0; i < n; i++) { + for (fnp = flist_op; *fnp; fnp++) { + if ((i & 1) == 0) + chown(*fnp, 2, -1); + else + chown(*fnp, 1, -1); + } + } +} + +/* ARGSUSED */ +static void +t_create(int n, void *v) +{ + int i; + + for (i = 0; i < n; i++) + crfiles(flist_op, fsize, buffer); +} + +/* ARGSUSED */ +static void +t_crunlink(int n, void *v) +{ + int i; + + for (i = 0; i < n; i++) { + crfiles(flist_op, fsize, buffer); + rmfiles(flist_op); + } +} + +#ifdef HAVE_GETDENTS +static void +t_getdents(int n, void *v) +{ + int eof; + struct getdents_data *g; + int i; + int j; + + for (g = v, i = 0; i < n; i++) { + (void)lseek(g->fd, 0, SEEK_SET); + eof = 0; + do { + j = ngetdents(g->fd, (dirent_t *)g->buffer, g->buflen, + &eof); + } while (j > 0 && eof == 0); + } +} +#endif + +/* ARGSUSED */ +static void +t_linkun(int n, void *v) +{ + char **fnp; + int i; + + for (i = 0; i < n; i++) { + for (fnp = flist_op; *fnp; fnp++) + link("a", *fnp); + rmfiles(flist_op); + } +} + +/* ARGSUSED */ +static void +t_open(int n, void *v) +{ + char **fnp; + int i; + + for (i = 0; i < n; i++) { + for (fnp = flist_op; *fnp; fnp++) + close(open(*fnp, O_RDWR)); + } +} + +static void +t_rename(int n, void *v) +{ + char **fnp; + int i; + char **rflist; + char **rfp; + + for (rflist = (char **)v, i = 0; i < n; i++) { + for (fnp = flist_op, rfp = rflist; *fnp; fnp++, rfp++) { + if ((i & 1) == 0) + rename(*fnp, *rfp); + else + rename(*rfp, *fnp); + } + } +} + +/* ARGSUSED */ +static void +t_stat(int n, void *v) +{ + char **fnp; + int i; + struct stat stb; + + for (i = 0; i < n; i++) { + for (fnp = flist_op; *fnp; fnp++) + stat(*fnp, &stb); + } +} + +static void +usage(void) +{ + fprintf(stderr, + "usage: metaperf [-d dname] [-i iters|-t seconds] [-s fsize]\n\t[-l opfnamelen] [-L bgfnamelen]\n\t[-n opfcount] [-N bgfcount] test...\n"); + fprintf(stderr, + "tests available: chown, create, crunlink, linkun, open, rename, stat\n"); + exit(1); +}