btrfs: test fstrim after doing a device replace
[xfstests-dev.git] / src / dbtest.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (c) 2000-2001 Silicon Graphics, Inc.
4  * All Rights Reserved.
5  */
6  
7 #include "global.h"
8
9 #ifdef HAVE_GDBM_NDBM_H_
10 #include <gdbm/ndbm.h>
11 #elif HAVE_GDBM_NDBM_H
12 #include <gdbm-ndbm.h>
13 #elif HAVE_NDBM_H
14 #include <ndbm.h>
15 #else
16 bozo!
17 #endif
18
19
20 /* #define WorkDir      "/xfs" */
21 #define DBNAME  "DBtest"
22 #define DBRECS  100000
23 #define LOOPS   100
24
25 typedef struct _myDB {
26         char            data[976];
27         unsigned short  checksum;
28         long            align;
29 } myDB; 
30
31 int InitDbmLookup(int);
32 int DoDbmLookup(void);
33 void CleanupDbmLookup(void);
34 void DoSysError(char *, int);
35 int creatDbRec(myDB *);
36 unsigned short calccksum(char *, int);
37 void CkSumError(char *, unsigned short, unsigned short);
38 int InsertKey(unsigned short *, int, unsigned short);
39 void DumpKeys(int, unsigned short);
40
41 DBM *dbm;
42 int numDbmEntries, keyIdx, Dups = 0, Errors = 0;
43 unsigned short *KeyArray, *DupsArray;
44 int debugflg = 0;       /* are we in debugging mode? */
45 int errflg = 0;         /* usage option errors */
46 int ignoreflg = 1;      /* ignore errors in lookup; default = on */
47 int loops = LOOPS;
48 int randseed = 0;
49
50 int
51 main(int argc, char *argv[])
52 {
53         int     numrecs = DBRECS, c, l;
54
55         while ((c = getopt(argc, argv, "idn:l:s:")) != EOF) {
56                 switch(c) {
57                         case 'i':
58                                 ignoreflg++; break;
59                         case 'd':
60                                 debugflg++; break;
61                         case 'n':
62                                 numrecs = atoi(optarg);
63                                 numrecs = (numrecs < 1) ? DBRECS : numrecs;
64                                 break;
65                         case 'l':
66                                 loops = atoi(optarg);
67                                 loops = (loops < 1) ? LOOPS : loops;
68                                 break;
69                         case 's':
70                                 randseed = atoi(optarg);
71                                 randseed = (randseed < 0) ? 0 : randseed;
72                                 break;
73                         case '?':
74                                 errflg++;
75                                 break;
76                 }
77         }
78         if (errflg) {
79                 printf("Usage: dbtest [-di] [-n number] [-l loop] [-s randseed]\n");
80                 exit(0);
81         }
82         if (optind > argc) {
83                 printf("Extra arguments ignored\n");
84                 for ( ; optind<argc; optind++)
85                         printf("\t%s\n", argv[optind]);
86         }
87
88         printf("dbtest v1.0\n\n");
89         printf("Creating database containing %d records...\n", numrecs);
90         printf("\tperforming lookups for %d iterations...\n", loops);
91         if (randseed)
92                 printf("\tusing %d as seed for srandom()...\n\n", randseed);
93         fflush(stdout);
94         InitDbmLookup(numrecs);
95         printf("\t\nThere were %d duplicate checksums generated\n", Dups);
96         for (l=0; l<loops; l++) {
97                 printf("\nPerforming lookups on database...\n");
98                 if (DoDbmLookup() != numrecs)
99                         printf("\nError performing lookups!\n");
100                 else
101                         printf("\nLookups succeeded...\n");
102         }
103         printf("\nCleaning up database...\n");
104         printf("\t\nThere were %d duplicate checksums generated\n", Dups);
105         fflush(stdout);
106         CleanupDbmLookup();
107         if (debugflg)
108                 for (l=0; l<Dups; l++) {
109                         if ((l % 8) == 0)
110                                 putchar('\n');
111                         printf("0x%x\t", DupsArray[l]);
112                 }
113
114         return 0;
115 }
116
117
118 int InitDbmLookup(int howmany)
119 {
120         char    filename[100];
121         datum   key, content;
122         int     i, rc;
123         myDB    dbRec;
124
125         sprintf(filename, "%s-%d", DBNAME, (int)getpid());
126         if (debugflg) {
127                 printf("dbm_open(%s, O_RDWR|O_CREAT, 0644)\n", filename);
128                 fflush(stdout);
129         }
130         dbm = dbm_open(filename, O_RDWR|O_CREAT, 0644);
131         if(dbm == NULL)
132                 DoSysError("\ndbm_open", -1);
133
134         if ((KeyArray = (unsigned short *)calloc( howmany,
135                                 sizeof(unsigned short))) == NULL)
136                 DoSysError("\ncalloc:KeyArray", -1);
137         if ((DupsArray = (unsigned short *)calloc( 100,
138                                 sizeof(unsigned short))) == NULL)
139                 DoSysError("\ncalloc:DupsArray", -1);
140
141         keyIdx = 0;
142         for(i=0; i<howmany; i++) {
143
144                 if ( creatDbRec(&dbRec) )
145                         DoSysError("\ncreatDbRec", -1);
146                 if (debugflg) {
147                         printf("created rec #%-7d\t%x\r", i+1, dbRec.checksum);
148                         fflush(stdout);
149                 }
150
151                 if (InsertKey(KeyArray, keyIdx, dbRec.checksum))
152                         keyIdx++;
153
154                 key.dptr = (char *)&(dbRec.checksum);
155                 key.dsize = sizeof(dbRec.checksum);
156                 content.dptr = (char *)&dbRec;
157                 content.dsize = sizeof(dbRec);
158
159                 write(2, NULL, 0);
160
161                 if (debugflg) {
162                         printf("dbm_store(dbm, key, content, DBM_INSERT)\n");
163                 }
164                 rc = dbm_store(dbm, key, content, DBM_INSERT);
165                 if (rc < 0)
166                         DoSysError("\ndbm_store", rc);
167                 else if (rc == 1) {
168                         keyIdx--;       /* key is already in database */
169                         DupsArray[Dups++] = dbRec.checksum;
170                 }
171         }
172         numDbmEntries = i;
173         if (debugflg) {
174                 printf("dbm_close(dbm)\n");
175                 fflush(stdout);
176         }
177         dbm_close(dbm); /* close to eliminate chance of in-memory caching */
178         if (debugflg) {
179                 printf("dbm_open(%s, O_RDONLY, 0)\n", filename);
180                 fflush(stdout);
181         }
182         dbm = dbm_open(filename, O_RDONLY, 0);
183         if(dbm == NULL)
184                 DoSysError("\ndbm_open", -1);
185         return 0;
186 }
187
188 int DoDbmLookup(void)
189 {
190         datum key, content;
191         int i, j, n;
192         myDB *dbp;
193         unsigned tmpck;
194
195         printf("\n\tSequential lookups...\n");
196         fflush(stdout);
197         for(i=0, j=0; i<numDbmEntries; i++) {
198                 key.dptr = (char *)(KeyArray+j);
199                 key.dsize = sizeof(KeyArray[0]);
200
201 write(2, NULL, 0);
202                 if (debugflg) {
203                         printf("dbm_fetch(dbm, key = %d)\n", j);
204                         fflush(stdout);
205                 }
206                 content = dbm_fetch(dbm, key);
207                 dbp = (myDB *)content.dptr;
208                 if ( !content.dptr ) {
209                         n = dbm_error(dbm);
210                         if (n) printf("\n\ndbm_error: %d\n", n);
211                         printf("\n%d: Sequential Lookup of key %4x failed!\n",
212                                 i, KeyArray[j]);
213                         DumpKeys(i, KeyArray[j]);
214                         Errors++;
215                         if (ignoreflg) {
216                                 j++;
217                                 continue;
218                         }
219                         assert( dbp );
220                 }
221
222                 if (debugflg && dbp) {
223                         printf("Seq rec #%-6d: checksum %4x (%4x)\r", i,
224                                 dbp->checksum, KeyArray[j]);
225                         fflush(stdout);
226                 }
227
228                 if (content.dsize == 0) {
229                         printf("\nrec #%-8d: key = %4x (%d)\n", i, KeyArray[j], j);
230                         fflush(stdout);
231                         DoSysError("\ndbm_fetch", content.dsize);
232                 }
233                 if (dbp->checksum != KeyArray[j])
234                         CkSumError("KeySequential", dbp->checksum, KeyArray[j]);
235                 if ((tmpck = calccksum(dbp->data, sizeof(dbp->data))) != KeyArray[j])
236                         CkSumError("DataSequential", tmpck, KeyArray[j]);
237                 if (++j >= keyIdx)
238                         j = 0;
239         }
240         printf("\n\n\tRandom lookups...\n");
241         fflush(stdout);
242         for(i=0; i<numDbmEntries; i++) {
243                 n = random() % keyIdx;
244                 key.dptr = (char *)(KeyArray+n);
245                 key.dsize = sizeof(KeyArray[0]);
246                 if (debugflg) {
247                         printf("dbm_fetch(dbm, key = %d)\n", n);
248                         fflush(stdout);
249                 }
250                 content = dbm_fetch(dbm, key);
251                 dbp = (myDB *)content.dptr;
252                 if ( !content.dptr ) {
253                         n = dbm_error(dbm);
254                         if (n) printf("\n\ndbm_error: %d\n", n);
255                         printf("\n%d: Random Lookup of key %4x failed!\n",
256                                 i, KeyArray[n]);
257                         DumpKeys(n, KeyArray[n]);
258                         Errors++;
259                         if (ignoreflg) {
260                                 continue;
261                         }
262                         assert( dbp );
263                 }
264
265                 if (debugflg && dbp) {
266                         printf("Rnd rec #%-6d: checksum %4x (%4x)\r", i,
267                                 dbp->checksum, KeyArray[n]);
268                         fflush(stdout);
269                 }
270
271                 if (content.dsize == 0)
272                         DoSysError("\ndbm_fetch", content.dsize);
273                 if (dbp->checksum != KeyArray[n])
274                         CkSumError("KeyRand", dbp->checksum, KeyArray[n]);
275                 if ((tmpck = calccksum(dbp->data, sizeof(dbp->data))) != KeyArray[n])
276                         CkSumError("DataRand", tmpck, KeyArray[n]);
277         }
278         return i;
279 }
280
281 void CleanupDbmLookup(void)
282 {
283         char filename[100];
284         int rc;
285
286         if (debugflg) {
287                 printf("dbm_close(dbm)\n");
288                 fflush(stdout);
289         }
290         dbm_close(dbm);
291         sprintf(filename, "%s-%d.dir", DBNAME, (int)getpid());
292         rc = unlink(filename);
293         if (rc) DoSysError("\nunlink", rc);
294         sprintf(filename, "%s-%d.pag", DBNAME, (int)getpid());
295         rc = unlink(filename);
296         if (rc) DoSysError("\nunlink", rc);
297 }
298
299 void DoSysError(char *msg, int rc)
300 {
301         perror(msg);
302         fprintf(stderr, "Bailing out! status = %d\n", rc);
303         exit(-1);
304 }
305
306 int creatDbRec(myDB *dbp)
307 {
308         static int once = 0;
309         int     i, j;
310         long    *ptr;
311         long    timeseed;
312
313         if (!once) {
314                 once++;
315                 if ( !randseed ) {
316                         timeseed = time(0);
317                         printf("\tusing %ld as seed for srandom()...\n\n",
318                                 timeseed);
319                         srandom(timeseed);
320                 } else
321                         srandom(randseed);
322         }
323         ptr = (long *)&(dbp->data);
324         j = sizeof(dbp->data) / sizeof(long);
325         for (i=0; i < j; i++, ptr++) {
326                 *ptr = random();
327         }
328         for (i=(j*sizeof(long)); i<sizeof(dbp->data); i++)
329                 dbp->data[i] = (char)time(0);
330
331         dbp->checksum = calccksum(dbp->data, sizeof(dbp->data));
332         return 0;
333 }
334
335 unsigned short calccksum(char *ptr, int size)
336 {
337         unsigned short sum;
338         int i, n;
339
340         sum = 0;
341         n = ((size > 100) ? 100 : size);
342         for (i=0; i<n && ptr; i++, ptr++) {
343                 if (sum & 01)
344                         sum = (sum >> 1) + 0x8000;
345                 else
346                         sum >>= 1;
347                 sum += (unsigned short)*ptr;
348                 sum &= 0xffff;
349         }
350         return sum;
351 }
352
353 /*ARGSUSED*/
354 void CkSumError(char *msg, unsigned short ck1, unsigned short ck2)
355 {
356         Errors++;
357         printf("%s\n\tChecksum error, %u != %u, Total errors = %d\n",
358                 msg, ck1, ck2, Errors);
359         exit(1);
360 }
361
362 int InsertKey(unsigned short *k, int idx, unsigned short val)
363 {
364 /*
365         int i, found=0;
366 */
367
368         return( (k[idx] = val) );
369
370 /*
371         for (i=0; i<idx; i++) {
372                 if (k[i] == val) {
373                         found++;
374                         break;
375                 }
376         }
377
378         if (!found)
379                 k[idx] = val;
380
381         return(!found);
382 */
383 }
384
385 void DumpKeys(int n, unsigned short key)
386 {
387 /*
388         int     i;
389         unsigned short *p;
390 */
391         FILE    *f;
392
393         if ((f = fopen("keys", "a")) == NULL) {
394                 perror("open(keys)");
395                 exit(1);
396         }
397 /*
398         for (i=0, p=arr; i<keyIdx && p; i++, p++)
399 */
400                 fprintf(f, "%d: 0x%x\n", n, key);
401
402         fclose(f);
403 }