/*
* Copyright (c) 1996 The University of Utah and
* the Computer Systems Laboratory at the University of Utah (CSL).
*
* This file is part of Flick, the Flexible IDL Compiler Kit.
*
* Flick is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* Flick is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Flick; see the file COPYING. If not, write to
* the Free Software Foundation, 59 Temple Place #330, Boston, MA 02111, USA.
*/
#include "yfs.h"
#include "ops.h"
#include <stdio.h>
#include <unistd.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#ifdef __cplusplus
extern "C" {
#endif
extern int random();
extern int srandom(int);
#ifdef __cplusplus
}
#endif
#if defined(__svr4__)
#define random rand
#define srandom(x) srand(x)
#endif
/* Set to FSCK if you have a fs check routine called yfs_fsck() */
#define NOFSCK
/* Set to RANDOMOFFSETS to do reads from random offsets */
#define NORANDOMOFFSETS
/* Number of items to generate (~1/3 will be directories) */
#define MAXITEMS 50
/* Number of writes to perform during the writes phase */
#define NUMWRITES 250
/* Maximum write size */
#define BLOCKSIZ 1000
#define ISGONE 0
#define ISDIR 1
#define ISFILE 2
#define MAXSIZE 10240
struct thing {
char *pn;
int whatisit;
int maxoffset;
int children;
int parent;
int num;
} genedpathname[MAXITEMS+1];
int getdiroffset(char *pn)
{
int i;
for (i=strlen(pn);i>=0;i--) {
if (pn[i]=='/')
return i;
}
printf("Error: pathname is not absolute!");
return -1;
}
#define CREATE 0
/* #define DELETE 1
#define WRITE 2
*/
#define ADIRECTORY 0
#define AFILE 1
void GenData(char *data, int num, int offset, int amount)
{
int data2[BLOCKSIZ/4+1];
int data2offset=(offset/4)*4;
int i;
for (i=0; i<BLOCKSIZ/4+1; i++) data2[i]=i+num+data2offset/4;
memcpy(data,((char *)data2)+(offset-data2offset),amount);
}
int do_op(char *pn, int op, int type, int offset,
char *buf, int len,
int *actual)
{
int diroff=getdiroffset(pn);
char *thedir=(char *)malloc(strlen(pn)+1);
char *thename=(char *)malloc(strlen(pn)+1);
Handle handle1;
Handle handle2;
int rc;
if (diroff==0) {
strcpy(thedir,"/");
strcpy(thename,&(pn[1]));
} else {
strncpy(thedir,pn,diroff);
thedir[diroff]=0;
strcpy(thename,&(pn[diroff+1]));
}
#if 0
printf("thedir='%s', thename='%s'\n",thedir, thename);
#endif
if ((handle1=Lookup(thedir,0))==-1) {
printf("ERROR: Lookup('%s',NULL) failed in do_op\n",thedir);
return -1;
}
#if 0
printf("looked up dir thename='%s'\n",thename);
#endif
switch (op) {
case CREATE:
switch(type) {
case ADIRECTORY:
return CreateDir(thename,handle1);
break;
case AFILE:
return CreateFile(thename,handle1);
break;
default:
printf("ERROR: Bad type in create\n");
}
break;
case DELETE:
if ((handle2=Lookup(thename,handle1))==-1) {
printf("ERROR: Lookup('%s',handleof('%s')) failed in do_op\n",thename,thedir);
return -1;
} else {
return Delete(thename,handle1);
}
break;
case WRITE:
if ((handle2=Lookup(thename,handle1))==-1) {
printf("ERROR: Lookup('%s',handleof('%s')) failed in do_op\n",thename,thedir);
return -1;
} else {
*actual=Write(handle2,len,offset,buf);
if (*actual==-1)
return -1;
else
return 0;
}
break;
case READ:
if ((handle2=Lookup(thename,handle1))==-1) {
printf("ERROR: Lookup('%s',handleof('%s')) failed in do_op\n",thename,thedir);
return -1;
} else {
*actual=Read(handle2,len,offset,buf);
if (*actual==-1)
return -1;
else
return 0;
}
break;
default:
printf("ERROR: Bad operation\n");
}
free(thedir);
free(thename);
return 0;
}
int main(int argc, char *argv[])
{
char buf[BLOCKSIZ], check[BLOCKSIZ];
int actualbs;
int rc;
int i,j;
int item;
int curbs;
int curoffset;
srandom(1234/*time(NULL) */);
for (i=0;i<BLOCKSIZ; i++)
buf[i]='Z';
genedpathname[0].pn="";
genedpathname[0].num=getpid();
genedpathname[0].whatisit=ISDIR;
genedpathname[0].children=0;
genedpathname[0].parent=-1;
printf("Now Generating %d files and directories\n", MAXITEMS);
for (i=1;i<=MAXITEMS;i++) {
do {
item=random()%i;
} while ((genedpathname[item].whatisit!=ISDIR));
if ((genedpathname[i].pn=(char*)malloc(
strlen(genedpathname[item].pn)+20))==NULL) {
printf("Out of memory\n");
exit(7);
}
genedpathname[item].children++;
genedpathname[i].parent=item;
genedpathname[i].children=0;
genedpathname[i].maxoffset=0;
genedpathname[i].num=random();
if (item==0)
{
sprintf(genedpathname[i].pn, "%s/%XX%X",genedpathname[item].pn,
genedpathname[item].num,genedpathname[i].num);
} else {
sprintf(genedpathname[i].pn, "%s/%X",genedpathname[item].pn,
genedpathname[i].num);
}
genedpathname[i].whatisit=random()%3 < 2 ? ISFILE : ISDIR;
printf("#%i %s - '%s'\n", i, genedpathname[i].whatisit==ISDIR ?
"DIR " : "FILE", genedpathname[i].pn);
if (genedpathname[i].whatisit==ISDIR) {
if (do_op(genedpathname[i].pn,CREATE,ADIRECTORY,0,0,0,0)) {
printf("ERROR: Failed to create dir %s\n",genedpathname[i].pn);
}
} else {
if (do_op(genedpathname[i].pn,CREATE,AFILE,0,0,0,0)) {
printf("ERROR: Failed to create file %s\n",genedpathname[i].pn);
}
}
#ifdef FSCK
if ((rc=yfs_fsck())) {
printf("ERROR: yfs_fsck returned %d\n", rc);
}
#endif
}
#ifdef FSCK
puts("(Complete FS Checks Run After Each File)");
#endif
printf("Now doing %d random writes to %d files\n",
NUMWRITES, MAXITEMS);
for (i=0;i<NUMWRITES;i++) {
do {
item=random()%MAXITEMS+1;
} while (genedpathname[item].whatisit!=ISFILE);
printf("#%d Trying to write to '%s'\n", i, genedpathname[item].pn);
curbs=random()%(BLOCKSIZ+1);
#ifdef RANDOMOFFSETS
curoffset=random()%MAXSIZE;
#else
curoffset=genedpathname[item].maxoffset;
#endif
curoffset=(curoffset+curbs>MAXSIZE) ? MAXSIZE-curbs : curoffset;
printf(" Try to write %d bytes at offset %d\n", curbs,curoffset);
GenData(buf,genedpathname[item].num,curoffset,curbs);
if (do_op(genedpathname[item].pn,WRITE,AFILE,curoffset,
buf,curbs,&actualbs)) {
printf("failed with rc=%d\n", rc);
}
if ((actualbs>0) && (actualbs+curoffset>genedpathname[item].maxoffset)) {
genedpathname[item].maxoffset=actualbs+curoffset;
}
if (actualbs!=curbs) {
printf("ERROR: Actually wrote %d bytes\n", actualbs);
}
#ifdef FSCK
if ((rc=yfs_fsck())) {
printf("ERROR: yfs_fsck returned %d\n", rc);
}
#endif
}
printf("Now doing sequential reads on %d files with readsize=%d\n",
MAXITEMS,BLOCKSIZ);
for (item=0;item<MAXITEMS;item++) {
if (genedpathname[item].whatisit==ISFILE) {
for (i=0;i+BLOCKSIZ-1<genedpathname[item].maxoffset;i+=BLOCKSIZ) {
printf("Reading file '%s', offset=%d, len=%d\n",
genedpathname[item].pn,i,BLOCKSIZ);
if (do_op(genedpathname[item].pn,READ,AFILE,i,
buf,BLOCKSIZ,&actualbs)) {
printf("ERROR: read failed!");
}
if (actualbs!=BLOCKSIZ) {
printf("ERROR: Only read %d bytes!\n",actualbs);
}
GenData(check,genedpathname[item].num,i,actualbs);
for (j=0;j<actualbs;j++) {
if (buf[j]!=check[j]) {
printf("ERROR: Read Bogus data!");
break;
}
}
}
/* Read spare stuff */
i=genedpathname[item].maxoffset-
genedpathname[item].maxoffset%BLOCKSIZ,
printf("Reading file '%s', offset=%d, len=%d\n",
genedpathname[item].pn,
i, genedpathname[item].maxoffset%BLOCKSIZ);
if (do_op(genedpathname[item].pn,READ,AFILE,i,
buf,genedpathname[item].maxoffset%BLOCKSIZ,&actualbs)) {
printf("ERROR: read failed!");
}
if (actualbs!=genedpathname[item].maxoffset%BLOCKSIZ) {
printf("ERROR: Only read %d bytes!\n",actualbs);
}
GenData(check,genedpathname[item].num,i,actualbs);
for (j=0;j<actualbs;j++) {
if (buf[j]!=check[j]) {
printf("ERROR: Read Bogus data!");
break;
}
}
}
#ifdef FSCK
if ((rc=yfs_fsck())) {
printf("ERROR: yfs_fsck returned %d\n", rc);
}
#endif
}
printf("Completed reads of all %d files\n", MAXITEMS);
printf("Now Deleting Files and Directories in Random Order\n");
i=1;
while (i<=MAXITEMS) {
/* Random is not random enough */
if (i<(MAXITEMS*4)/5)
{
do {
item=random()%(MAXITEMS) + 1;
} while ((genedpathname[item].whatisit==ISGONE) ||
(genedpathname[item].children>0));
} else
{
for (item=1; item<=MAXITEMS; item++)
if (genedpathname[item].whatisit!=ISGONE &&
genedpathname[item].children==0)
break;
}
/* Now we have a random item */
genedpathname[genedpathname[item].parent].children--;
printf("Deleting #%d %s - '%s'\n", i,
genedpathname[item].whatisit==ISDIR ?
"DIR " : "FILE", genedpathname[item].pn);
if (genedpathname[item].whatisit==ISDIR) {
if (do_op(genedpathname[item].pn,DELETE,ADIRECTORY,0,0,0,0)) {
printf("ERROR: Delete failed - check why!\n");
}
} else {
if (do_op(genedpathname[item].pn,DELETE,AFILE,0,0,0,0)) {
printf("ERROR: Delete failed - check why!\n");
}
}
genedpathname[item].whatisit=ISGONE;
++i;
#ifdef FSCK
if ((rc=yfs_fsck())) {
printf("ERROR: yfs_fsck returned %d\n", rc);
}
#endif
}
puts("Done");
exit(0);
}
syntax highlighted by Code2HTML, v. 0.9.1