mirror of
https://github.com/sqlite/sqlite.git
synced 2025-11-15 11:41:13 +03:00
Add a test for the outcome of a process crash within an xWrite VFS method
call. FossilOrigin-Name: eb8718006cb23ba9304da5c30d19863d688495f0eaae3794c5ad870e481866f8
This commit is contained in:
@@ -28,6 +28,7 @@
|
||||
** Name used to identify this VFS.
|
||||
*/
|
||||
#define DEVSYM_VFS_NAME "devsym"
|
||||
#define WRITECRASH_NAME "writecrash"
|
||||
|
||||
typedef struct devsym_file devsym_file;
|
||||
struct devsym_file {
|
||||
@@ -72,61 +73,13 @@ static int devsymRandomness(sqlite3_vfs*, int nByte, char *zOut);
|
||||
static int devsymSleep(sqlite3_vfs*, int microseconds);
|
||||
static int devsymCurrentTime(sqlite3_vfs*, double*);
|
||||
|
||||
static sqlite3_vfs devsym_vfs = {
|
||||
2, /* iVersion */
|
||||
sizeof(devsym_file), /* szOsFile */
|
||||
DEVSYM_MAX_PATHNAME, /* mxPathname */
|
||||
0, /* pNext */
|
||||
DEVSYM_VFS_NAME, /* zName */
|
||||
0, /* pAppData */
|
||||
devsymOpen, /* xOpen */
|
||||
devsymDelete, /* xDelete */
|
||||
devsymAccess, /* xAccess */
|
||||
devsymFullPathname, /* xFullPathname */
|
||||
#ifndef SQLITE_OMIT_LOAD_EXTENSION
|
||||
devsymDlOpen, /* xDlOpen */
|
||||
devsymDlError, /* xDlError */
|
||||
devsymDlSym, /* xDlSym */
|
||||
devsymDlClose, /* xDlClose */
|
||||
#else
|
||||
0, /* xDlOpen */
|
||||
0, /* xDlError */
|
||||
0, /* xDlSym */
|
||||
0, /* xDlClose */
|
||||
#endif /* SQLITE_OMIT_LOAD_EXTENSION */
|
||||
devsymRandomness, /* xRandomness */
|
||||
devsymSleep, /* xSleep */
|
||||
devsymCurrentTime, /* xCurrentTime */
|
||||
0, /* xGetLastError */
|
||||
0 /* xCurrentTimeInt64 */
|
||||
};
|
||||
|
||||
static sqlite3_io_methods devsym_io_methods = {
|
||||
2, /* iVersion */
|
||||
devsymClose, /* xClose */
|
||||
devsymRead, /* xRead */
|
||||
devsymWrite, /* xWrite */
|
||||
devsymTruncate, /* xTruncate */
|
||||
devsymSync, /* xSync */
|
||||
devsymFileSize, /* xFileSize */
|
||||
devsymLock, /* xLock */
|
||||
devsymUnlock, /* xUnlock */
|
||||
devsymCheckReservedLock, /* xCheckReservedLock */
|
||||
devsymFileControl, /* xFileControl */
|
||||
devsymSectorSize, /* xSectorSize */
|
||||
devsymDeviceCharacteristics, /* xDeviceCharacteristics */
|
||||
devsymShmMap, /* xShmMap */
|
||||
devsymShmLock, /* xShmLock */
|
||||
devsymShmBarrier, /* xShmBarrier */
|
||||
devsymShmUnmap /* xShmUnmap */
|
||||
};
|
||||
|
||||
struct DevsymGlobal {
|
||||
sqlite3_vfs *pVfs;
|
||||
int iDeviceChar;
|
||||
int iSectorSize;
|
||||
int nWriteCrash;
|
||||
};
|
||||
struct DevsymGlobal g = {0, 0, 512};
|
||||
struct DevsymGlobal g = {0, 0, 512, 0};
|
||||
|
||||
/*
|
||||
** Close an devsym-file.
|
||||
@@ -271,6 +224,26 @@ static int devsymOpen(
|
||||
int flags,
|
||||
int *pOutFlags
|
||||
){
|
||||
static sqlite3_io_methods devsym_io_methods = {
|
||||
2, /* iVersion */
|
||||
devsymClose, /* xClose */
|
||||
devsymRead, /* xRead */
|
||||
devsymWrite, /* xWrite */
|
||||
devsymTruncate, /* xTruncate */
|
||||
devsymSync, /* xSync */
|
||||
devsymFileSize, /* xFileSize */
|
||||
devsymLock, /* xLock */
|
||||
devsymUnlock, /* xUnlock */
|
||||
devsymCheckReservedLock, /* xCheckReservedLock */
|
||||
devsymFileControl, /* xFileControl */
|
||||
devsymSectorSize, /* xSectorSize */
|
||||
devsymDeviceCharacteristics, /* xDeviceCharacteristics */
|
||||
devsymShmMap, /* xShmMap */
|
||||
devsymShmLock, /* xShmLock */
|
||||
devsymShmBarrier, /* xShmBarrier */
|
||||
devsymShmUnmap /* xShmUnmap */
|
||||
};
|
||||
|
||||
int rc;
|
||||
devsym_file *p = (devsym_file *)pFile;
|
||||
p->pReal = (sqlite3_file *)&p[1];
|
||||
@@ -372,6 +345,137 @@ static int devsymCurrentTime(sqlite3_vfs *pVfs, double *pTimeOut){
|
||||
return g.pVfs->xCurrentTime(g.pVfs, pTimeOut);
|
||||
}
|
||||
|
||||
/*
|
||||
** Return the sector-size in bytes for an writecrash-file.
|
||||
*/
|
||||
static int writecrashSectorSize(sqlite3_file *pFile){
|
||||
devsym_file *p = (devsym_file *)pFile;
|
||||
return sqlite3OsSectorSize(p->pReal);
|
||||
}
|
||||
|
||||
/*
|
||||
** Return the device characteristic flags supported by an writecrash-file.
|
||||
*/
|
||||
static int writecrashDeviceCharacteristics(sqlite3_file *pFile){
|
||||
devsym_file *p = (devsym_file *)pFile;
|
||||
return sqlite3OsDeviceCharacteristics(p->pReal);
|
||||
}
|
||||
|
||||
/*
|
||||
** Write data to an writecrash-file.
|
||||
*/
|
||||
static int writecrashWrite(
|
||||
sqlite3_file *pFile,
|
||||
const void *zBuf,
|
||||
int iAmt,
|
||||
sqlite_int64 iOfst
|
||||
){
|
||||
devsym_file *p = (devsym_file *)pFile;
|
||||
if( g.nWriteCrash>0 ){
|
||||
g.nWriteCrash--;
|
||||
if( g.nWriteCrash==0 ) abort();
|
||||
}
|
||||
return sqlite3OsWrite(p->pReal, zBuf, iAmt, iOfst);
|
||||
}
|
||||
|
||||
/*
|
||||
** Open an writecrash file handle.
|
||||
*/
|
||||
static int writecrashOpen(
|
||||
sqlite3_vfs *pVfs,
|
||||
const char *zName,
|
||||
sqlite3_file *pFile,
|
||||
int flags,
|
||||
int *pOutFlags
|
||||
){
|
||||
static sqlite3_io_methods writecrash_io_methods = {
|
||||
2, /* iVersion */
|
||||
devsymClose, /* xClose */
|
||||
devsymRead, /* xRead */
|
||||
writecrashWrite, /* xWrite */
|
||||
devsymTruncate, /* xTruncate */
|
||||
devsymSync, /* xSync */
|
||||
devsymFileSize, /* xFileSize */
|
||||
devsymLock, /* xLock */
|
||||
devsymUnlock, /* xUnlock */
|
||||
devsymCheckReservedLock, /* xCheckReservedLock */
|
||||
devsymFileControl, /* xFileControl */
|
||||
writecrashSectorSize, /* xSectorSize */
|
||||
writecrashDeviceCharacteristics, /* xDeviceCharacteristics */
|
||||
devsymShmMap, /* xShmMap */
|
||||
devsymShmLock, /* xShmLock */
|
||||
devsymShmBarrier, /* xShmBarrier */
|
||||
devsymShmUnmap /* xShmUnmap */
|
||||
};
|
||||
|
||||
int rc;
|
||||
devsym_file *p = (devsym_file *)pFile;
|
||||
p->pReal = (sqlite3_file *)&p[1];
|
||||
rc = sqlite3OsOpen(g.pVfs, zName, p->pReal, flags, pOutFlags);
|
||||
if( p->pReal->pMethods ){
|
||||
pFile->pMethods = &writecrash_io_methods;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
static sqlite3_vfs devsym_vfs = {
|
||||
2, /* iVersion */
|
||||
sizeof(devsym_file), /* szOsFile */
|
||||
DEVSYM_MAX_PATHNAME, /* mxPathname */
|
||||
0, /* pNext */
|
||||
DEVSYM_VFS_NAME, /* zName */
|
||||
0, /* pAppData */
|
||||
devsymOpen, /* xOpen */
|
||||
devsymDelete, /* xDelete */
|
||||
devsymAccess, /* xAccess */
|
||||
devsymFullPathname, /* xFullPathname */
|
||||
#ifndef SQLITE_OMIT_LOAD_EXTENSION
|
||||
devsymDlOpen, /* xDlOpen */
|
||||
devsymDlError, /* xDlError */
|
||||
devsymDlSym, /* xDlSym */
|
||||
devsymDlClose, /* xDlClose */
|
||||
#else
|
||||
0, /* xDlOpen */
|
||||
0, /* xDlError */
|
||||
0, /* xDlSym */
|
||||
0, /* xDlClose */
|
||||
#endif /* SQLITE_OMIT_LOAD_EXTENSION */
|
||||
devsymRandomness, /* xRandomness */
|
||||
devsymSleep, /* xSleep */
|
||||
devsymCurrentTime, /* xCurrentTime */
|
||||
0, /* xGetLastError */
|
||||
0 /* xCurrentTimeInt64 */
|
||||
};
|
||||
|
||||
static sqlite3_vfs writecrash_vfs = {
|
||||
2, /* iVersion */
|
||||
sizeof(devsym_file), /* szOsFile */
|
||||
DEVSYM_MAX_PATHNAME, /* mxPathname */
|
||||
0, /* pNext */
|
||||
WRITECRASH_NAME, /* zName */
|
||||
0, /* pAppData */
|
||||
writecrashOpen, /* xOpen */
|
||||
devsymDelete, /* xDelete */
|
||||
devsymAccess, /* xAccess */
|
||||
devsymFullPathname, /* xFullPathname */
|
||||
#ifndef SQLITE_OMIT_LOAD_EXTENSION
|
||||
devsymDlOpen, /* xDlOpen */
|
||||
devsymDlError, /* xDlError */
|
||||
devsymDlSym, /* xDlSym */
|
||||
devsymDlClose, /* xDlClose */
|
||||
#else
|
||||
0, /* xDlOpen */
|
||||
0, /* xDlError */
|
||||
0, /* xDlSym */
|
||||
0, /* xDlClose */
|
||||
#endif /* SQLITE_OMIT_LOAD_EXTENSION */
|
||||
devsymRandomness, /* xRandomness */
|
||||
devsymSleep, /* xSleep */
|
||||
devsymCurrentTime, /* xCurrentTime */
|
||||
0, /* xGetLastError */
|
||||
0 /* xCurrentTimeInt64 */
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
** This procedure registers the devsym vfs with SQLite. If the argument is
|
||||
@@ -379,10 +483,13 @@ static int devsymCurrentTime(sqlite3_vfs *pVfs, double *pTimeOut){
|
||||
** available function in this file.
|
||||
*/
|
||||
void devsym_register(int iDeviceChar, int iSectorSize){
|
||||
|
||||
if( g.pVfs==0 ){
|
||||
g.pVfs = sqlite3_vfs_find(0);
|
||||
devsym_vfs.szOsFile += g.pVfs->szOsFile;
|
||||
writecrash_vfs.szOsFile += g.pVfs->szOsFile;
|
||||
sqlite3_vfs_register(&devsym_vfs, 0);
|
||||
sqlite3_vfs_register(&writecrash_vfs, 0);
|
||||
}
|
||||
if( iDeviceChar>=0 ){
|
||||
g.iDeviceChar = iDeviceChar;
|
||||
@@ -403,4 +510,15 @@ void devsym_unregister(){
|
||||
g.iSectorSize = 0;
|
||||
}
|
||||
|
||||
void devsym_crash_on_write(int nWrite){
|
||||
if( g.pVfs==0 ){
|
||||
g.pVfs = sqlite3_vfs_find(0);
|
||||
devsym_vfs.szOsFile += g.pVfs->szOsFile;
|
||||
writecrash_vfs.szOsFile += g.pVfs->szOsFile;
|
||||
sqlite3_vfs_register(&devsym_vfs, 0);
|
||||
sqlite3_vfs_register(&writecrash_vfs, 0);
|
||||
}
|
||||
g.nWriteCrash = nWrite;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user