1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-10-25 20:58:26 +03:00

Enhanced I/O error simulation. (CVS 3418)

FossilOrigin-Name: 86931854fc5a63571719639d9a23b1d6614a6153
This commit is contained in:
drh
2006-09-14 13:47:11 +00:00
parent f800e3e63a
commit 5968593b51
6 changed files with 58 additions and 41 deletions

View File

@@ -92,18 +92,18 @@ int sqlite3_io_error_hit = 0;
int sqlite3_io_error_pending = 0;
int sqlite3_diskfull_pending = 0;
int sqlite3_diskfull = 0;
#define SimulateIOError(A) \
#define SimulateIOError(CODE) \
if( sqlite3_io_error_pending ) \
if( sqlite3_io_error_pending-- == 1 ){ local_ioerr(); return A; }
if( sqlite3_io_error_pending-- == 1 ){ local_ioerr(); CODE; }
static void local_ioerr(){
sqlite3_io_error_hit = 1; /* Really just a place to set a breakpoint */
}
#define SimulateDiskfullError \
#define SimulateDiskfullError(CODE) \
if( sqlite3_diskfull_pending ){ \
if( sqlite3_diskfull_pending == 1 ){ \
local_ioerr(); \
sqlite3_diskfull = 1; \
return SQLITE_FULL; \
CODE; \
}else{ \
sqlite3_diskfull_pending--; \
} \

View File

@@ -287,7 +287,7 @@ int os2Close( OsFile **pld ){
int os2Read( OsFile *id, void *pBuf, int amt ){
ULONG got;
assert( id!=0 );
SimulateIOError( SQLITE_IOERR );
SimulateIOError( return SQLITE_IOERR );
TRACE3( "READ %d lock=%d\n", ((os2File*)id)->h, ((os2File*)id)->locktype );
DosRead( ((os2File*)id)->h, pBuf, amt, &got );
return (got == (ULONG)amt) ? SQLITE_OK : SQLITE_IOERR;
@@ -301,8 +301,8 @@ int os2Write( OsFile *id, const void *pBuf, int amt ){
APIRET rc = NO_ERROR;
ULONG wrote;
assert( id!=0 );
SimulateIOError( SQLITE_IOERR );
SimulateDiskfullError;
SimulateIOError( return SQLITE_IOERR );
SimulateDiskfullError( return SQLITE_FULL );
TRACE3( "WRITE %d lock=%d\n", ((os2File*)id)->h, ((os2File*)id)->locktype );
while( amt > 0 &&
(rc = DosWrite( ((os2File*)id)->h, (PVOID)pBuf, amt, &wrote )) && wrote > 0 ){
@@ -339,7 +339,7 @@ int os2Sync( OsFile *id, int dataOnly ){
** than UNIX.
*/
int sqlite3Os2SyncDirectory( const char *zDirname ){
SimulateIOError( SQLITE_IOERR );
SimulateIOError( return SQLITE_IOERR );
return SQLITE_OK;
}
@@ -351,7 +351,7 @@ int os2Truncate( OsFile *id, i64 nByte ){
ULONG upperBits = nByte>>32;
assert( id!=0 );
TRACE3( "TRUNCATE %d %lld\n", ((os2File*)id)->h, nByte );
SimulateIOError( SQLITE_IOERR );
SimulateIOError( return SQLITE_IOERR );
rc = DosSetFilePtr( ((os2File*)id)->h, nByte, FILE_BEGIN, &upperBits );
if( rc != NO_ERROR ){
return SQLITE_IOERR;
@@ -368,7 +368,7 @@ int os2FileSize( OsFile *id, i64 *pSize ){
FILESTATUS3 fsts3FileInfo;
memset(&fsts3FileInfo, 0, sizeof(fsts3FileInfo));
assert( id!=0 );
SimulateIOError( SQLITE_IOERR );
SimulateIOError( return SQLITE_IOERR );
rc = DosQueryFileInfo( ((os2File*)id)->h, FIL_STANDARD, &fsts3FileInfo, sizeof(FILESTATUS3) );
if( rc == NO_ERROR ){
*pSize = fsts3FileInfo.cbFile;

View File

@@ -928,14 +928,13 @@ static int seekAndRead(unixFile *id, void *pBuf, int cnt){
static int unixRead(OsFile *id, void *pBuf, int amt){
int got;
assert( id );
SimulateIOError(SQLITE_IOERR);
TIMER_START;
got = seekAndRead((unixFile*)id, pBuf, amt);
TIMER_END;
TRACE5("READ %-3d %5d %7d %d\n", ((unixFile*)id)->h, got,
last_page, TIMER_ELAPSED);
SEEK(0);
/* if( got<0 ) got = 0; */
SimulateIOError( got=0 );
if( got==amt ){
return SQLITE_OK;
}else{
@@ -970,8 +969,6 @@ static int unixWrite(OsFile *id, const void *pBuf, int amt){
int wrote = 0;
assert( id );
assert( amt>0 );
SimulateIOError(SQLITE_IOERR);
SimulateDiskfullError;
TIMER_START;
while( amt>0 && (wrote = seekAndWrite((unixFile*)id, pBuf, amt))>0 ){
amt -= wrote;
@@ -981,8 +978,14 @@ static int unixWrite(OsFile *id, const void *pBuf, int amt){
TRACE5("WRITE %-3d %5d %7d %d\n", ((unixFile*)id)->h, wrote,
last_page, TIMER_ELAPSED);
SEEK(0);
SimulateIOError(( wrote=(-1), amt=1 ));
SimulateDiskfullError(( wrote=0, amt=1 ));
if( amt>0 ){
return SQLITE_FULL;
if( wrote<0 ){
return SQLITE_IOERR;
}else{
return SQLITE_FULL;
}
}
return SQLITE_OK;
}
@@ -994,7 +997,7 @@ static int unixSeek(OsFile *id, i64 offset){
assert( id );
SEEK(offset/1024 + 1);
#ifdef SQLITE_TEST
if( offset ) SimulateDiskfullError
if( offset ) SimulateDiskfullError(return SQLITE_FULL);
#endif
((unixFile*)id)->offset = offset;
return SQLITE_OK;
@@ -1096,11 +1099,13 @@ static int full_fsync(int fd, int fullSync, int dataOnly){
** will not roll back - possibly leading to database corruption.
*/
static int unixSync(OsFile *id, int dataOnly){
int rc;
unixFile *pFile = (unixFile*)id;
assert( pFile );
SimulateIOError(SQLITE_IOERR);
TRACE2("SYNC %-3d\n", pFile->h);
if( full_fsync(pFile->h, pFile->fullSync, dataOnly) ){
rc = full_fsync(pFile->h, pFile->fullSync, dataOnly);
SimulateIOError( rc=1 );
if( rc ){
return SQLITE_IOERR;
}
if( pFile->dirfd>=0 ){
@@ -1141,7 +1146,6 @@ int sqlite3UnixSyncDirectory(const char *zDirname){
#else
int fd;
int r;
SimulateIOError(SQLITE_IOERR);
fd = open(zDirname, O_RDONLY|O_BINARY, 0);
TRACE3("DIRSYNC %-3d (%s)\n", fd, zDirname);
if( fd<0 ){
@@ -1149,7 +1153,12 @@ int sqlite3UnixSyncDirectory(const char *zDirname){
}
r = fsync(fd);
close(fd);
return ((r==0)?SQLITE_OK:SQLITE_IOERR);
SimulateIOError( r=1 );
if( r ){
return SQLITE_IOERR;
}else{
return SQLITE_OK;
}
#endif
}
@@ -1157,19 +1166,27 @@ int sqlite3UnixSyncDirectory(const char *zDirname){
** Truncate an open file to a specified size
*/
static int unixTruncate(OsFile *id, i64 nByte){
int rc;
assert( id );
SimulateIOError(SQLITE_IOERR);
return ftruncate(((unixFile*)id)->h, nByte)==0 ? SQLITE_OK : SQLITE_IOERR;
rc = ftruncate(((unixFile*)id)->h, nByte);
SimulateIOError( rc=1 );
if( rc ){
return SQLITE_IOERR;
}else{
return SQLITE_OK;
}
}
/*
** Determine the current size of a file in bytes
*/
static int unixFileSize(OsFile *id, i64 *pSize){
int rc;
struct stat buf;
assert( id );
SimulateIOError(SQLITE_IOERR);
if( fstat(((unixFile*)id)->h, &buf)!=0 ){
rc = fstat(((unixFile*)id)->h, &buf);
SimulateIOError( rc=1 );
if( rc!=0 ){
return SQLITE_IOERR;
}
*pSize = buf.st_size;

View File

@@ -864,7 +864,7 @@ static int winClose(OsFile **pId){
static int winRead(OsFile *id, void *pBuf, int amt){
DWORD got;
assert( id!=0 );
SimulateIOError(SQLITE_IOERR);
SimulateIOError(return SQLITE_IOERR);
TRACE3("READ %d lock=%d\n", ((winFile*)id)->h, ((winFile*)id)->locktype);
if( !ReadFile(((winFile*)id)->h, pBuf, amt, &got, 0) ){
got = 0;
@@ -884,8 +884,8 @@ static int winWrite(OsFile *id, const void *pBuf, int amt){
int rc = 0;
DWORD wrote;
assert( id!=0 );
SimulateIOError(SQLITE_IOERR);
SimulateDiskfullError;
SimulateIOError(return SQLITE_IOERR);
SimulateDiskfullError(return SQLITE_FULL);
TRACE3("WRITE %d lock=%d\n", ((winFile*)id)->h, ((winFile*)id)->locktype);
assert( amt>0 );
while( amt>0 && (rc = WriteFile(((winFile*)id)->h, pBuf, amt, &wrote, 0))!=0
@@ -915,7 +915,7 @@ static int winSeek(OsFile *id, i64 offset){
DWORD rc;
assert( id!=0 );
#ifdef SQLITE_TEST
if( offset ) SimulateDiskfullError
if( offset ) SimulateDiskfullError(return SQLITE_FULL);
#endif
SEEK(offset/1024 + 1);
rc = SetFilePointer(((winFile*)id)->h, lowerBits, &upperBits, FILE_BEGIN);
@@ -944,7 +944,7 @@ static int winSync(OsFile *id, int dataOnly){
** than UNIX.
*/
int sqlite3WinSyncDirectory(const char *zDirname){
SimulateIOError(SQLITE_IOERR);
SimulateIOError(return SQLITE_IOERR);
return SQLITE_OK;
}
@@ -955,7 +955,7 @@ static int winTruncate(OsFile *id, i64 nByte){
LONG upperBits = nByte>>32;
assert( id!=0 );
TRACE3("TRUNCATE %d %lld\n", ((winFile*)id)->h, nByte);
SimulateIOError(SQLITE_IOERR);
SimulateIOError(return SQLITE_IOERR);
SetFilePointer(((winFile*)id)->h, nByte, &upperBits, FILE_BEGIN);
SetEndOfFile(((winFile*)id)->h);
return SQLITE_OK;
@@ -967,7 +967,7 @@ static int winTruncate(OsFile *id, i64 nByte){
static int winFileSize(OsFile *id, i64 *pSize){
DWORD upperBits, lowerBits;
assert( id!=0 );
SimulateIOError(SQLITE_IOERR);
SimulateIOError(return SQLITE_IOERR);
lowerBits = GetFileSize(((winFile*)id)->h, &upperBits);
*pSize = (((i64)upperBits)<<32) + lowerBits;
return SQLITE_OK;