sos-code-article10/userland/blktest.c

209 lines
6.5 KiB
C

/* Copyright (C) 2005,2006 David Decotigny
This program 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.
This program 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 this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
USA.
*/
#include <crt.h>
#include <libc.h>
#include <stdarg.h>
#include <string.h>
#include <debug.h>
#include <drivers/devices.h>
#include "fstest_utils.h"
/**
* @file blktest.c
*
* Block devices tests
*/
static int test_device(char const* path, char magic)
{
char wrbuff[32767];
char rdbuff[32767];
int fd, fdcheck, i;
char * mem;
fd = open(path, O_RDWR);
if (fd < 0)
{
bochs_printf("Cannot open %s: error %d\n", path, fd);
return -1;
}
bochs_printf("Testing %s...\n", path);
/* Basic seek tests */
TEST_EXPECT_CONDITION(lseek(fd, 2*512, SEEK_SET), RETVAL == 2*512);
TEST_EXPECT_CONDITION(write(fd, wrbuff, 1), RETVAL == 1);
TEST_EXPECT_CONDITION(lseek(fd, 4*512, SEEK_SET), RETVAL == 4*512);
TEST_EXPECT_CONDITION(read(fd, rdbuff, 1), RETVAL == 1);
/* Prepare to write a large chunk */
for (i = 0 ; i < sizeof(wrbuff) ; i ++)
wrbuff[i] = magic + i;
memset(rdbuff, 0xaa, sizeof(wrbuff));
TEST_EXPECT_CONDITION(lseek(fd, 3*512 + 43, SEEK_SET), RETVAL == 3*512 + 43);
TEST_EXPECT_CONDITION(write(fd, wrbuff, sizeof(wrbuff)),
RETVAL == sizeof(wrbuff));
TEST_EXPECT_CONDITION(write(fd, rdbuff, sizeof(rdbuff)),
RETVAL == sizeof(rdbuff));
memset(rdbuff, 0xbb, sizeof(rdbuff));
TEST_EXPECT_CONDITION(lseek(fd, 3*512 + 47, SEEK_SET), RETVAL == 3*512 + 47);
TEST_EXPECT_CONDITION(read(fd, rdbuff, sizeof(wrbuff)),
RETVAL == sizeof(wrbuff));
TEST_EXPECT_CONDITION(memcmp(rdbuff, wrbuff+4, sizeof(wrbuff)-4),
RETVAL == 0);
fdcheck = open(path, O_RDONLY);
#define MAPOFFS (50*4096)
/* Test mmap private mappings */
TEST_EXPECT_CONDITION(mem = mmap(NULL, sizeof(wrbuff), PROT_READ,
MAP_PRIVATE, fd, MAPOFFS + 3),
(void*)RETVAL == NULL);
TEST_EXPECT_CONDITION(mem = mmap(NULL, sizeof(wrbuff),
PROT_READ | PROT_WRITE, MAP_PRIVATE,
fd, MAPOFFS),
(void*)RETVAL != NULL);
for (i = 0 ; i < sizeof(wrbuff) ; i ++)
wrbuff[i] = magic + i;
TEST_EXPECT_CONDITION(1, 1); /* Print a debug line */
memset(rdbuff, 0xaa, sizeof(wrbuff));
TEST_EXPECT_CONDITION(lseek(fd, MAPOFFS, SEEK_SET), RETVAL == MAPOFFS);
TEST_EXPECT_CONDITION(write(fd, wrbuff, sizeof(wrbuff)),
RETVAL == sizeof(wrbuff));
TEST_EXPECT_CONDITION(memcmp(wrbuff, mem, sizeof(wrbuff)),
RETVAL == 0);
for (i = 0 ; i < sizeof(wrbuff) ; i ++)
mem[i] = wrbuff[i]*i;
TEST_EXPECT_CONDITION(1, 1); /* Print a debug line */
memset(rdbuff, 0xaa, sizeof(rdbuff));
TEST_EXPECT_CONDITION(lseek(fdcheck, MAPOFFS, SEEK_SET), RETVAL == MAPOFFS);
TEST_EXPECT_CONDITION(read(fdcheck, rdbuff, sizeof(wrbuff)),
RETVAL == sizeof(wrbuff));
TEST_EXPECT_CONDITION(memcmp(wrbuff, rdbuff, sizeof(wrbuff)), RETVAL == 0);
TEST_EXPECT_CONDITION(msync(mem, sizeof(wrbuff), MS_SYNC), RETVAL == 0);
TEST_EXPECT_CONDITION(munmap(mem, sizeof(wrbuff)), RETVAL == 0);
/* Test mmap shared mappings */
TEST_EXPECT_CONDITION(mem = mmap(mem, sizeof(wrbuff), PROT_READ,
MAP_SHARED, fd, MAPOFFS + 3),
(void*)RETVAL == NULL);
TEST_EXPECT_CONDITION(mem = mmap(mem, sizeof(wrbuff),
PROT_READ | PROT_WRITE, MAP_SHARED,
fd, MAPOFFS),
(void*)RETVAL != NULL);
for (i = 0 ; i < sizeof(wrbuff) ; i ++)
wrbuff[i] = magic + i;
memset(rdbuff, 0xaa, sizeof(rdbuff));
TEST_EXPECT_CONDITION(lseek(fd, MAPOFFS, SEEK_SET), RETVAL == MAPOFFS);
TEST_EXPECT_CONDITION(write(fd, wrbuff, sizeof(wrbuff)),
RETVAL == sizeof(wrbuff));
TEST_EXPECT_CONDITION(memcmp(wrbuff, mem, sizeof(wrbuff)), RETVAL == 0);
for (i = 0 ; i < sizeof(wrbuff) ; i ++)
mem[i] = wrbuff[i]*i;
memset(rdbuff, 0xaa, sizeof(rdbuff));
TEST_EXPECT_CONDITION(lseek(fdcheck, MAPOFFS, SEEK_SET), RETVAL == MAPOFFS);
TEST_EXPECT_CONDITION(read(fdcheck, rdbuff, sizeof(wrbuff)),
RETVAL == sizeof(wrbuff));
TEST_EXPECT_CONDITION(memcmp(wrbuff, rdbuff, sizeof(wrbuff)), RETVAL != 0);
TEST_EXPECT_CONDITION(memcmp(mem, rdbuff, sizeof(wrbuff)), RETVAL == 0);
TEST_EXPECT_CONDITION(msync(mem, sizeof(wrbuff), MS_SYNC), RETVAL == 0);
TEST_EXPECT_CONDITION(munmap(mem, sizeof(wrbuff)), RETVAL == 0);
#define STARTOFFS (3*512 + 43 + sizeof(wrbuff) + sizeof(rdbuff))
TEST_EXPECT_CONDITION(lseek(fd, STARTOFFS, SEEK_SET), RETVAL == STARTOFFS);
TEST_EXPECT_CONDITION(lseek(fdcheck, STARTOFFS, SEEK_SET),
RETVAL == STARTOFFS);
int wrlen = 0;
while (1)
{
int sz;
for (i = 0 ; i < sizeof(wrbuff) ; i ++)
wrbuff[i] = magic*magic*i + wrlen*wrlen + i;
TEST_EXPECT_CONDITION(sz = write(fd, wrbuff, sizeof(wrbuff)),
(RETVAL >= 0) && (RETVAL <= sizeof(wrbuff)));
if (sz <= 0)
break;
wrlen += sz;
memset(rdbuff, 0xcc, sizeof(wrbuff));
TEST_EXPECT_CONDITION(read(fdcheck, rdbuff, sizeof(wrbuff)), RETVAL == sz);
TEST_EXPECT_CONDITION(memcmp(rdbuff, wrbuff, sz), RETVAL == 0);
}
/* Check the data was correctly written */
TEST_EXPECT_CONDITION(lseek(fd, STARTOFFS, SEEK_SET), RETVAL == STARTOFFS);
int rdlen = 0;
while (1)
{
int sz;
for (i = 0 ; i < sizeof(wrbuff) ; i ++)
wrbuff[i] = magic*magic*i + rdlen*rdlen + i;
memset(rdbuff, 0xdd, sizeof(wrbuff));
TEST_EXPECT_CONDITION(sz = read(fd, rdbuff, sizeof(wrbuff)),
(RETVAL >= 0) && (RETVAL <= sizeof(wrbuff)));
if (sz <= 0)
break;
rdlen += sz;
TEST_EXPECT_CONDITION(memcmp(rdbuff, wrbuff, sz), RETVAL == 0);
}
TEST_EXPECT_CONDITION(rdlen, wrlen == rdlen);
bochs_printf("Synching %s...\n", path);
ioctl(fd, SOS_IOCTL_BLOCKDEV_SYNC, 0);
close(fd);
bochs_printf("End of test for %s.\n", path);
return 0;
}
int main(void)
{
int i;
bochs_printf("Hi from blktest\n");
/* Test partitions access */
for (i = 1 ; i <= 15 ; i ++)
{
char path[64];
snprintf(path, sizeof(path), "/dev/hda%d", i);
if (fork() == 0)
{
test_device(path, i);
return 0;
}
}
bochs_printf("Bye from blktest\n");
return 0;
}