/* * Copyright (c) 1996-2000 University of Utah and the Flux Group. * All rights reserved. * * This file is part of the Flux OSKit. The OSKit is free software, also known * as "open source;" you can redistribute it and/or modify it under the terms * of the GNU General Public License (GPL), version 2, as published by the Free * Software Foundation (FSF). To explore alternate licensing terms, contact * the University of Utah at csl-dist@cs.utah.edu or +1-801-585-3271. * * The OSKit 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 GPL for more details. You should have * received a copy of the GPL along with the OSKit; see the file COPYING. If * not, write to the FSF, 59 Temple Place #330, Boston, MA 02111-1307, USA. */ /* * This is an example OS-Kit program that tests the disk code in the * block device drivers. It reads blocks of data from the disk. * You can change REALLY_WRITE to control writing to the disk. If there * is a problem, the contents of the disk may no longer be valid. * However, *IF* everything works correctly, this program will restore * the previous contents of the disk when it is done. */ #include #include #include #include #include #include #include #include #include #include #include #include #include /* _exit */ oskit_blkio_t *io; /* #define REALLY_WRITE if you want to actually write. */ /* These are in terms of SECTORS. */ int test_offset[] = { 0, 1, 3, 7, 8, 63, 64, 127, 128, 1024, 1025 }; int test_size[] = { 1, 2, 5, 11, 8, 63, 64, 128, 129, 333, 1024, 1025 }; #define n_offsets (sizeof(test_offset) / sizeof(test_offset[0])) #define n_sizes (sizeof(test_size) / sizeof(test_size[0])) int read_test(int offset, int size, char *buf) { int err, amt; #ifdef DEBUG_TEST printf("Reading %d bytes at offset %d\n", size, offset); #endif err = oskit_blkio_read(io, buf, offset, size, &amt); if (err) { printf(" Read ERROR %08x\n", err); return(1); } #ifdef DEBUG_TEST printf("Read done, amt = %d of %d\n", amt, size); #endif return 0; } #ifdef REALLY_WRITE int write_test(int offset, int size, char *buf) { int err, amt; #ifdef DEBUG_TEST printf("Writing %d bytes at offset %d\n", size, offset); #endif err = oskit_blkio_write(io, buf, offset, size, &amt); if (err || amt != size) { printf(" Write ERROR %d\n", err); return(1); } #ifdef DEBUG_TEST printf("Wrote %d of %d bytes!\n", amt, size); #endif return 0; } #endif /* REALLY_WRITE */ /* * This runs tests on a bunch of disk blocks. * Generally, these should be an integral multiple of sectors aligned * on a sector boundary. */ int test_block(int offset, int size) { char *wbuf; #ifdef REALLY_WRITE char *vbuf; int i; #endif /* Allocate memory for the data */ wbuf = smemalign(512, size); if (!wbuf) { printf(" can't allocate buf!\n"); _exit(1); } memset(wbuf, 0xA5, size); #ifdef REALLY_WRITE vbuf = smemalign(512, size); if (!vbuf) { printf(" can't allocate buf!\n"); _exit(1); } memset(vbuf, 0xA5, size); #endif #ifdef REALLY_WRITE printf("Doing read test of %d bytes at offset %d\n", size, offset); #else printf("Doing read test of %d bytes at offset %d\n", size, offset); #endif /* Read in blocks from the disk. */ if (read_test(offset, size, wbuf)) return -1; #ifdef DEBUG_TEST printf("read %x\n", wbuf[0] & 0xff); #endif #ifdef REALLY_WRITE /* * Okay, here we change the data (invert the bits), and * write it back out. */ for (i = 0; i < size; i++) wbuf[i] = ~wbuf[i]; printf("Doing write test of %d bytes at offset %d\n", size, offset); if (write_test(offset, size, wbuf)) return -1; #ifdef DEBUG_TEST printf("inverted bits\n"); printf("wrote %x\n", wbuf[0] & 0xff); #endif /* After we write it out, we read it back, and check it. */ if (read_test(offset, size, vbuf)) { printf("Error reading back data!\n"); return -1; } #ifdef DEBUG_TEST printf("read %x\n", vbuf[0] & 0xff); #endif /* now, make sure they are all the same... */ for (i = 0; i < size; i++) if (wbuf[i] != vbuf[i]) { printf("ERROR: differing at byte %d (%x != %x)\n", i, wbuf[i], vbuf[i]); break; /* to avoid TONS of errors... */ } /* Restore the data, and re-write it out. */ for (i = 0; i < size; i++) wbuf[i] = ~wbuf[i]; if (write_test(offset, size, wbuf)) return -1; #ifdef DEBUG_TEST printf("inverted bits\n"); printf("wrote %x\n", wbuf[0] & 0xff); #endif /* release the write-test memory */ sfree(vbuf, size); #endif /* REALLY_WRITE */ /* release the memory */ sfree(wbuf, size); return 0; } int main(int argc, char **argv) { int rc; int err = 0; char name[10]; oskit_size_t sec_size; oskit_off_t disk_size; int n_tests, i, j; #ifndef KNIT oskit_clientos_init(); start_blk_devices(); #endif oskit_dump_devices(); #ifdef GPROF start_fs_bmod(); start_gprof(); pause_gprof(0); #endif #ifdef REALLY_WRITE printf("\nWARNING: Doing Read/Write test.\n"); #else printf("\nDoing Read-Only test.\n"); #endif /* * Get the drive name to test from the user. * We don't want to trash the wrong disk ... */ do { printf("\nEnter drive name to test, `quit' to exit: "); gets(name); if (!strcmp(name, "quit")) return 1; if (!strcmp(name, "")) continue; printf("Opening disk %s...\n", name); err = oskit_linux_block_open(name, OSKIT_DEV_OPEN_READ #ifdef REALLY_WRITE | OSKIT_DEV_OPEN_WRITE #endif , &io); if (err) { if (err == OSKIT_E_DEV_NOSUCH_DEV) printf("disk %s does not exist!\n", name); else printf("error %x opening disk %s\n", err, name); } } while (err); sec_size = oskit_blkio_getblocksize(io); printf("disk native sectors are %d bytes\n", sec_size); if (oskit_blkio_getsize(io, &disk_size)) { printf("Can't determine disk size...assuming the disk is big enough!\n"); disk_size = (test_offset[n_offsets - 1] + test_size[n_sizes - 1]) * sec_size; } else printf("size of disk is %d kbytes\n", (unsigned int)(disk_size >> 10)); n_tests = n_offsets; printf("\nRunning %d tests\n\n", n_tests); #ifdef GPROF pause_gprof(1); #endif for (i = 0; i < n_tests; i++) { for (j = 0; j < n_sizes; j++) { if (((test_offset[i] + test_size[j]) * sec_size) <= disk_size) { rc = test_block(test_offset[i] * sec_size, test_size[j] * sec_size); if (rc) { printf("\nEXITING: errors in the disk tests.\n"); oskit_blkio_release(io); return rc; } } } } #ifdef GPROF pause_gprof(0); #endif oskit_blkio_release(io); printf("\nTests completed with no errors.\n"); return 0; }