1
0

test6.c 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020
  1. /*
  2. ** 2004 May 22
  3. **
  4. ** The author disclaims copyright to this source code. In place of
  5. ** a legal notice, here is a blessing:
  6. **
  7. ** May you do good and not evil.
  8. ** May you find forgiveness for yourself and forgive others.
  9. ** May you share freely, never taking more than you give.
  10. **
  11. ******************************************************************************
  12. **
  13. ** This file contains code that modified the OS layer in order to simulate
  14. ** the effect on the database file of an OS crash or power failure. This
  15. ** is used to test the ability of SQLite to recover from those situations.
  16. */
  17. #if SQLITE_TEST /* This file is used for testing only */
  18. #include "sqliteInt.h"
  19. #include "tcl.h"
  20. #ifndef SQLITE_OMIT_DISKIO /* This file is a no-op if disk I/O is disabled */
  21. /* #define TRACE_CRASHTEST */
  22. typedef struct CrashFile CrashFile;
  23. typedef struct CrashGlobal CrashGlobal;
  24. typedef struct WriteBuffer WriteBuffer;
  25. /*
  26. ** Method:
  27. **
  28. ** This layer is implemented as a wrapper around the "real"
  29. ** sqlite3_file object for the host system. Each time data is
  30. ** written to the file object, instead of being written to the
  31. ** underlying file, the write operation is stored in an in-memory
  32. ** structure (type WriteBuffer). This structure is placed at the
  33. ** end of a global ordered list (the write-list).
  34. **
  35. ** When data is read from a file object, the requested region is
  36. ** first retrieved from the real file. The write-list is then
  37. ** traversed and data copied from any overlapping WriteBuffer
  38. ** structures to the output buffer. i.e. a read() operation following
  39. ** one or more write() operations works as expected, even if no
  40. ** data has actually been written out to the real file.
  41. **
  42. ** When a fsync() operation is performed, an operating system crash
  43. ** may be simulated, in which case exit(-1) is called (the call to
  44. ** xSync() never returns). Whether or not a crash is simulated,
  45. ** the data associated with a subset of the WriteBuffer structures
  46. ** stored in the write-list is written to the real underlying files
  47. ** and the entries removed from the write-list. If a crash is simulated,
  48. ** a subset of the buffers may be corrupted before the data is written.
  49. **
  50. ** The exact subset of the write-list written and/or corrupted is
  51. ** determined by the simulated device characteristics and sector-size.
  52. **
  53. ** "Normal" mode:
  54. **
  55. ** Normal mode is used when the simulated device has none of the
  56. ** SQLITE_IOCAP_XXX flags set.
  57. **
  58. ** In normal mode, if the fsync() is not a simulated crash, the
  59. ** write-list is traversed from beginning to end. Each WriteBuffer
  60. ** structure associated with the file handle used to call xSync()
  61. ** is written to the real file and removed from the write-list.
  62. **
  63. ** If a crash is simulated, one of the following takes place for
  64. ** each WriteBuffer in the write-list, regardless of which
  65. ** file-handle it is associated with:
  66. **
  67. ** 1. The buffer is correctly written to the file, just as if
  68. ** a crash were not being simulated.
  69. **
  70. ** 2. Nothing is done.
  71. **
  72. ** 3. Garbage data is written to all sectors of the file that
  73. ** overlap the region specified by the WriteBuffer. Or garbage
  74. ** data is written to some contiguous section within the
  75. ** overlapped sectors.
  76. **
  77. ** Device Characteristic flag handling:
  78. **
  79. ** If the IOCAP_ATOMIC flag is set, then option (3) above is
  80. ** never selected.
  81. **
  82. ** If the IOCAP_ATOMIC512 flag is set, and the WriteBuffer represents
  83. ** an aligned write() of an integer number of 512 byte regions, then
  84. ** option (3) above is never selected. Instead, each 512 byte region
  85. ** is either correctly written or left completely untouched. Similar
  86. ** logic governs the behavior if any of the other ATOMICXXX flags
  87. ** is set.
  88. **
  89. ** If either the IOCAP_SAFEAPPEND or IOCAP_SEQUENTIAL flags are set
  90. ** and a crash is being simulated, then an entry of the write-list is
  91. ** selected at random. Everything in the list after the selected entry
  92. ** is discarded before processing begins.
  93. **
  94. ** If IOCAP_SEQUENTIAL is set and a crash is being simulated, option
  95. ** (1) is selected for all write-list entries except the last. If a
  96. ** crash is not being simulated, then all entries in the write-list
  97. ** that occur before at least one write() on the file-handle specified
  98. ** as part of the xSync() are written to their associated real files.
  99. **
  100. ** If IOCAP_SAFEAPPEND is set and the first byte written by the write()
  101. ** operation is one byte past the current end of the file, then option
  102. ** (1) is always selected.
  103. */
  104. /*
  105. ** Each write operation in the write-list is represented by an instance
  106. ** of the following structure.
  107. **
  108. ** If zBuf is 0, then this structure represents a call to xTruncate(),
  109. ** not xWrite(). In that case, iOffset is the size that the file is
  110. ** truncated to.
  111. */
  112. struct WriteBuffer {
  113. i64 iOffset; /* Byte offset of the start of this write() */
  114. int nBuf; /* Number of bytes written */
  115. u8 *zBuf; /* Pointer to copy of written data */
  116. CrashFile *pFile; /* File this write() applies to */
  117. WriteBuffer *pNext; /* Next in CrashGlobal.pWriteList */
  118. };
  119. struct CrashFile {
  120. const sqlite3_io_methods *pMethod; /* Must be first */
  121. sqlite3_file *pRealFile; /* Underlying "real" file handle */
  122. char *zName;
  123. int flags; /* Flags the file was opened with */
  124. /* Cache of the entire file. This is used to speed up OsRead() and
  125. ** OsFileSize() calls. Although both could be done by traversing the
  126. ** write-list, in practice this is impractically slow.
  127. */
  128. u8 *zData; /* Buffer containing file contents */
  129. int nData; /* Size of buffer allocated at zData */
  130. i64 iSize; /* Size of file in bytes */
  131. };
  132. struct CrashGlobal {
  133. WriteBuffer *pWriteList; /* Head of write-list */
  134. WriteBuffer *pWriteListEnd; /* End of write-list */
  135. int iSectorSize; /* Value of simulated sector size */
  136. int iDeviceCharacteristics; /* Value of simulated device characteristics */
  137. int iCrash; /* Crash on the iCrash'th call to xSync() */
  138. char zCrashFile[500]; /* Crash during an xSync() on this file */
  139. };
  140. static CrashGlobal g = {0, 0, SQLITE_DEFAULT_SECTOR_SIZE, 0, 0};
  141. /*
  142. ** Set this global variable to 1 to enable crash testing.
  143. */
  144. static int sqlite3CrashTestEnable = 0;
  145. static void *crash_malloc(int nByte){
  146. return (void *)Tcl_Alloc((size_t)nByte);
  147. }
  148. static void crash_free(void *p){
  149. Tcl_Free(p);
  150. }
  151. static void *crash_realloc(void *p, int n){
  152. return (void *)Tcl_Realloc(p, (size_t)n);
  153. }
  154. /*
  155. ** Wrapper around the sqlite3OsWrite() function that avoids writing to the
  156. ** 512 byte block begining at offset PENDING_BYTE.
  157. */
  158. static int writeDbFile(CrashFile *p, u8 *z, i64 iAmt, i64 iOff){
  159. int rc = SQLITE_OK;
  160. int iSkip = 0;
  161. if( iOff==PENDING_BYTE && (p->flags&SQLITE_OPEN_MAIN_DB) ){
  162. iSkip = 512;
  163. }
  164. if( (iAmt-iSkip)>0 ){
  165. rc = sqlite3OsWrite(p->pRealFile, &z[iSkip], (int)(iAmt-iSkip), iOff+iSkip);
  166. }
  167. return rc;
  168. }
  169. /*
  170. ** Flush the write-list as if xSync() had been called on file handle
  171. ** pFile. If isCrash is true, simulate a crash.
  172. */
  173. static int writeListSync(CrashFile *pFile, int isCrash){
  174. int rc = SQLITE_OK;
  175. int iDc = g.iDeviceCharacteristics;
  176. WriteBuffer *pWrite;
  177. WriteBuffer **ppPtr;
  178. /* If this is not a crash simulation, set pFinal to point to the
  179. ** last element of the write-list that is associated with file handle
  180. ** pFile.
  181. **
  182. ** If this is a crash simulation, set pFinal to an arbitrarily selected
  183. ** element of the write-list.
  184. */
  185. WriteBuffer *pFinal = 0;
  186. if( !isCrash ){
  187. for(pWrite=g.pWriteList; pWrite; pWrite=pWrite->pNext){
  188. if( pWrite->pFile==pFile ){
  189. pFinal = pWrite;
  190. }
  191. }
  192. }else if( iDc&(SQLITE_IOCAP_SEQUENTIAL|SQLITE_IOCAP_SAFE_APPEND) ){
  193. int nWrite = 0;
  194. int iFinal;
  195. for(pWrite=g.pWriteList; pWrite; pWrite=pWrite->pNext) nWrite++;
  196. sqlite3_randomness(sizeof(int), &iFinal);
  197. iFinal = ((iFinal<0)?-1*iFinal:iFinal)%nWrite;
  198. for(pWrite=g.pWriteList; iFinal>0; pWrite=pWrite->pNext) iFinal--;
  199. pFinal = pWrite;
  200. }
  201. #ifdef TRACE_CRASHTEST
  202. printf("Sync %s (is %s crash)\n", pFile->zName, (isCrash?"a":"not a"));
  203. #endif
  204. ppPtr = &g.pWriteList;
  205. for(pWrite=*ppPtr; rc==SQLITE_OK && pWrite; pWrite=*ppPtr){
  206. sqlite3_file *pRealFile = pWrite->pFile->pRealFile;
  207. /* (eAction==1) -> write block out normally,
  208. ** (eAction==2) -> do nothing,
  209. ** (eAction==3) -> trash sectors.
  210. */
  211. int eAction = 0;
  212. if( !isCrash ){
  213. eAction = 2;
  214. if( (pWrite->pFile==pFile || iDc&SQLITE_IOCAP_SEQUENTIAL) ){
  215. eAction = 1;
  216. }
  217. }else{
  218. char random;
  219. sqlite3_randomness(1, &random);
  220. /* Do not select option 3 (sector trashing) if the IOCAP_ATOMIC flag
  221. ** is set or this is an OsTruncate(), not an Oswrite().
  222. */
  223. if( (iDc&SQLITE_IOCAP_ATOMIC) || (pWrite->zBuf==0) ){
  224. random &= 0x01;
  225. }
  226. /* If IOCAP_SEQUENTIAL is set and this is not the final entry
  227. ** in the truncated write-list, always select option 1 (write
  228. ** out correctly).
  229. */
  230. if( (iDc&SQLITE_IOCAP_SEQUENTIAL && pWrite!=pFinal) ){
  231. random = 0;
  232. }
  233. /* If IOCAP_SAFE_APPEND is set and this OsWrite() operation is
  234. ** an append (first byte of the written region is 1 byte past the
  235. ** current EOF), always select option 1 (write out correctly).
  236. */
  237. if( iDc&SQLITE_IOCAP_SAFE_APPEND && pWrite->zBuf ){
  238. i64 iSize;
  239. sqlite3OsFileSize(pRealFile, &iSize);
  240. if( iSize==pWrite->iOffset ){
  241. random = 0;
  242. }
  243. }
  244. if( (random&0x06)==0x06 ){
  245. eAction = 3;
  246. }else{
  247. eAction = ((random&0x01)?2:1);
  248. }
  249. }
  250. switch( eAction ){
  251. case 1: { /* Write out correctly */
  252. if( pWrite->zBuf ){
  253. rc = writeDbFile(
  254. pWrite->pFile, pWrite->zBuf, pWrite->nBuf, pWrite->iOffset
  255. );
  256. }else{
  257. rc = sqlite3OsTruncate(pRealFile, pWrite->iOffset);
  258. }
  259. *ppPtr = pWrite->pNext;
  260. #ifdef TRACE_CRASHTEST
  261. if( isCrash ){
  262. printf("Writing %d bytes @ %d (%s)\n",
  263. pWrite->nBuf, (int)pWrite->iOffset, pWrite->pFile->zName
  264. );
  265. }
  266. #endif
  267. crash_free(pWrite);
  268. break;
  269. }
  270. case 2: { /* Do nothing */
  271. ppPtr = &pWrite->pNext;
  272. #ifdef TRACE_CRASHTEST
  273. if( isCrash ){
  274. printf("Omiting %d bytes @ %d (%s)\n",
  275. pWrite->nBuf, (int)pWrite->iOffset, pWrite->pFile->zName
  276. );
  277. }
  278. #endif
  279. break;
  280. }
  281. case 3: { /* Trash sectors */
  282. u8 *zGarbage;
  283. int iFirst = (int)(pWrite->iOffset/g.iSectorSize);
  284. int iLast = (int)((pWrite->iOffset+pWrite->nBuf-1)/g.iSectorSize);
  285. assert(pWrite->zBuf);
  286. #ifdef TRACE_CRASHTEST
  287. printf("Trashing %d sectors @ %lld (sector %d) (%s)\n",
  288. 1+iLast-iFirst, pWrite->iOffset, iFirst, pWrite->pFile->zName
  289. );
  290. #endif
  291. zGarbage = crash_malloc(g.iSectorSize);
  292. if( zGarbage ){
  293. sqlite3_int64 i;
  294. for(i=iFirst; rc==SQLITE_OK && i<=iLast; i++){
  295. sqlite3_randomness(g.iSectorSize, zGarbage);
  296. rc = writeDbFile(
  297. pWrite->pFile, zGarbage, g.iSectorSize, i*g.iSectorSize
  298. );
  299. }
  300. crash_free(zGarbage);
  301. }else{
  302. rc = SQLITE_NOMEM;
  303. }
  304. ppPtr = &pWrite->pNext;
  305. break;
  306. }
  307. default:
  308. assert(!"Cannot happen");
  309. }
  310. if( pWrite==pFinal ) break;
  311. }
  312. if( rc==SQLITE_OK && isCrash ){
  313. exit(-1);
  314. }
  315. for(pWrite=g.pWriteList; pWrite && pWrite->pNext; pWrite=pWrite->pNext);
  316. g.pWriteListEnd = pWrite;
  317. return rc;
  318. }
  319. /*
  320. ** Add an entry to the end of the write-list.
  321. */
  322. static int writeListAppend(
  323. sqlite3_file *pFile,
  324. sqlite3_int64 iOffset,
  325. const u8 *zBuf,
  326. int nBuf
  327. ){
  328. WriteBuffer *pNew;
  329. assert((zBuf && nBuf) || (!nBuf && !zBuf));
  330. pNew = (WriteBuffer *)crash_malloc(sizeof(WriteBuffer) + nBuf);
  331. if( pNew==0 ){
  332. fprintf(stderr, "out of memory in the crash simulator\n");
  333. }
  334. memset(pNew, 0, sizeof(WriteBuffer)+nBuf);
  335. pNew->iOffset = iOffset;
  336. pNew->nBuf = nBuf;
  337. pNew->pFile = (CrashFile *)pFile;
  338. if( zBuf ){
  339. pNew->zBuf = (u8 *)&pNew[1];
  340. memcpy(pNew->zBuf, zBuf, nBuf);
  341. }
  342. if( g.pWriteList ){
  343. assert(g.pWriteListEnd);
  344. g.pWriteListEnd->pNext = pNew;
  345. }else{
  346. g.pWriteList = pNew;
  347. }
  348. g.pWriteListEnd = pNew;
  349. return SQLITE_OK;
  350. }
  351. /*
  352. ** Close a crash-file.
  353. */
  354. static int cfClose(sqlite3_file *pFile){
  355. CrashFile *pCrash = (CrashFile *)pFile;
  356. writeListSync(pCrash, 0);
  357. sqlite3OsClose(pCrash->pRealFile);
  358. return SQLITE_OK;
  359. }
  360. /*
  361. ** Read data from a crash-file.
  362. */
  363. static int cfRead(
  364. sqlite3_file *pFile,
  365. void *zBuf,
  366. int iAmt,
  367. sqlite_int64 iOfst
  368. ){
  369. CrashFile *pCrash = (CrashFile *)pFile;
  370. /* Check the file-size to see if this is a short-read */
  371. if( pCrash->iSize<(iOfst+iAmt) ){
  372. return SQLITE_IOERR_SHORT_READ;
  373. }
  374. memcpy(zBuf, &pCrash->zData[iOfst], iAmt);
  375. return SQLITE_OK;
  376. }
  377. /*
  378. ** Write data to a crash-file.
  379. */
  380. static int cfWrite(
  381. sqlite3_file *pFile,
  382. const void *zBuf,
  383. int iAmt,
  384. sqlite_int64 iOfst
  385. ){
  386. CrashFile *pCrash = (CrashFile *)pFile;
  387. if( iAmt+iOfst>pCrash->iSize ){
  388. pCrash->iSize = (int)(iAmt+iOfst);
  389. }
  390. while( pCrash->iSize>pCrash->nData ){
  391. u8 *zNew;
  392. int nNew = (pCrash->nData*2) + 4096;
  393. zNew = crash_realloc(pCrash->zData, nNew);
  394. if( !zNew ){
  395. return SQLITE_NOMEM;
  396. }
  397. memset(&zNew[pCrash->nData], 0, nNew-pCrash->nData);
  398. pCrash->nData = nNew;
  399. pCrash->zData = zNew;
  400. }
  401. memcpy(&pCrash->zData[iOfst], zBuf, iAmt);
  402. return writeListAppend(pFile, iOfst, zBuf, iAmt);
  403. }
  404. /*
  405. ** Truncate a crash-file.
  406. */
  407. static int cfTruncate(sqlite3_file *pFile, sqlite_int64 size){
  408. CrashFile *pCrash = (CrashFile *)pFile;
  409. assert(size>=0);
  410. if( pCrash->iSize>size ){
  411. pCrash->iSize = (int)size;
  412. }
  413. return writeListAppend(pFile, size, 0, 0);
  414. }
  415. /*
  416. ** Sync a crash-file.
  417. */
  418. static int cfSync(sqlite3_file *pFile, int flags){
  419. CrashFile *pCrash = (CrashFile *)pFile;
  420. int isCrash = 0;
  421. const char *zName = pCrash->zName;
  422. const char *zCrashFile = g.zCrashFile;
  423. int nName = (int)strlen(zName);
  424. int nCrashFile = (int)strlen(zCrashFile);
  425. if( nCrashFile>0 && zCrashFile[nCrashFile-1]=='*' ){
  426. nCrashFile--;
  427. if( nName>nCrashFile ) nName = nCrashFile;
  428. }
  429. #ifdef TRACE_CRASHTEST
  430. printf("cfSync(): nName = %d, nCrashFile = %d, zName = %s, zCrashFile = %s\n",
  431. nName, nCrashFile, zName, zCrashFile);
  432. #endif
  433. if( nName==nCrashFile && 0==memcmp(zName, zCrashFile, nName) ){
  434. #ifdef TRACE_CRASHTEST
  435. printf("cfSync(): name matched, g.iCrash = %d\n", g.iCrash);
  436. #endif
  437. if( (--g.iCrash)==0 ) isCrash = 1;
  438. }
  439. return writeListSync(pCrash, isCrash);
  440. }
  441. /*
  442. ** Return the current file-size of the crash-file.
  443. */
  444. static int cfFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){
  445. CrashFile *pCrash = (CrashFile *)pFile;
  446. *pSize = (i64)pCrash->iSize;
  447. return SQLITE_OK;
  448. }
  449. /*
  450. ** Calls related to file-locks are passed on to the real file handle.
  451. */
  452. static int cfLock(sqlite3_file *pFile, int eLock){
  453. return sqlite3OsLock(((CrashFile *)pFile)->pRealFile, eLock);
  454. }
  455. static int cfUnlock(sqlite3_file *pFile, int eLock){
  456. return sqlite3OsUnlock(((CrashFile *)pFile)->pRealFile, eLock);
  457. }
  458. static int cfCheckReservedLock(sqlite3_file *pFile, int *pResOut){
  459. return sqlite3OsCheckReservedLock(((CrashFile *)pFile)->pRealFile, pResOut);
  460. }
  461. static int cfFileControl(sqlite3_file *pFile, int op, void *pArg){
  462. if( op==SQLITE_FCNTL_SIZE_HINT ){
  463. CrashFile *pCrash = (CrashFile *)pFile;
  464. i64 nByte = *(i64 *)pArg;
  465. if( nByte>pCrash->iSize ){
  466. if( SQLITE_OK==writeListAppend(pFile, nByte, 0, 0) ){
  467. pCrash->iSize = (int)nByte;
  468. }
  469. }
  470. return SQLITE_OK;
  471. }
  472. return sqlite3OsFileControl(((CrashFile *)pFile)->pRealFile, op, pArg);
  473. }
  474. /*
  475. ** The xSectorSize() and xDeviceCharacteristics() functions return
  476. ** the global values configured by the [sqlite_crashparams] tcl
  477. * interface.
  478. */
  479. static int cfSectorSize(sqlite3_file *pFile){
  480. return g.iSectorSize;
  481. }
  482. static int cfDeviceCharacteristics(sqlite3_file *pFile){
  483. return g.iDeviceCharacteristics;
  484. }
  485. /*
  486. ** Pass-throughs for WAL support.
  487. */
  488. static int cfShmLock(sqlite3_file *pFile, int ofst, int n, int flags){
  489. return sqlite3OsShmLock(((CrashFile*)pFile)->pRealFile, ofst, n, flags);
  490. }
  491. static void cfShmBarrier(sqlite3_file *pFile){
  492. sqlite3OsShmBarrier(((CrashFile*)pFile)->pRealFile);
  493. }
  494. static int cfShmUnmap(sqlite3_file *pFile, int delFlag){
  495. return sqlite3OsShmUnmap(((CrashFile*)pFile)->pRealFile, delFlag);
  496. }
  497. static int cfShmMap(
  498. sqlite3_file *pFile, /* Handle open on database file */
  499. int iRegion, /* Region to retrieve */
  500. int sz, /* Size of regions */
  501. int w, /* True to extend file if necessary */
  502. void volatile **pp /* OUT: Mapped memory */
  503. ){
  504. return sqlite3OsShmMap(((CrashFile*)pFile)->pRealFile, iRegion, sz, w, pp);
  505. }
  506. static const sqlite3_io_methods CrashFileVtab = {
  507. 2, /* iVersion */
  508. cfClose, /* xClose */
  509. cfRead, /* xRead */
  510. cfWrite, /* xWrite */
  511. cfTruncate, /* xTruncate */
  512. cfSync, /* xSync */
  513. cfFileSize, /* xFileSize */
  514. cfLock, /* xLock */
  515. cfUnlock, /* xUnlock */
  516. cfCheckReservedLock, /* xCheckReservedLock */
  517. cfFileControl, /* xFileControl */
  518. cfSectorSize, /* xSectorSize */
  519. cfDeviceCharacteristics, /* xDeviceCharacteristics */
  520. cfShmMap, /* xShmMap */
  521. cfShmLock, /* xShmLock */
  522. cfShmBarrier, /* xShmBarrier */
  523. cfShmUnmap /* xShmUnmap */
  524. };
  525. /*
  526. ** Application data for the crash VFS
  527. */
  528. struct crashAppData {
  529. sqlite3_vfs *pOrig; /* Wrapped vfs structure */
  530. };
  531. /*
  532. ** Open a crash-file file handle.
  533. **
  534. ** The caller will have allocated pVfs->szOsFile bytes of space
  535. ** at pFile. This file uses this space for the CrashFile structure
  536. ** and allocates space for the "real" file structure using
  537. ** sqlite3_malloc(). The assumption here is (pVfs->szOsFile) is
  538. ** equal or greater than sizeof(CrashFile).
  539. */
  540. static int cfOpen(
  541. sqlite3_vfs *pCfVfs,
  542. const char *zName,
  543. sqlite3_file *pFile,
  544. int flags,
  545. int *pOutFlags
  546. ){
  547. sqlite3_vfs *pVfs = (sqlite3_vfs *)pCfVfs->pAppData;
  548. int rc;
  549. CrashFile *pWrapper = (CrashFile *)pFile;
  550. sqlite3_file *pReal = (sqlite3_file*)&pWrapper[1];
  551. memset(pWrapper, 0, sizeof(CrashFile));
  552. rc = sqlite3OsOpen(pVfs, zName, pReal, flags, pOutFlags);
  553. if( rc==SQLITE_OK ){
  554. i64 iSize;
  555. pWrapper->pMethod = &CrashFileVtab;
  556. pWrapper->zName = (char *)zName;
  557. pWrapper->pRealFile = pReal;
  558. rc = sqlite3OsFileSize(pReal, &iSize);
  559. pWrapper->iSize = (int)iSize;
  560. pWrapper->flags = flags;
  561. }
  562. if( rc==SQLITE_OK ){
  563. pWrapper->nData = (4096 + pWrapper->iSize);
  564. pWrapper->zData = crash_malloc(pWrapper->nData);
  565. if( pWrapper->zData ){
  566. /* os_unix.c contains an assert() that fails if the caller attempts
  567. ** to read data from the 512-byte locking region of a file opened
  568. ** with the SQLITE_OPEN_MAIN_DB flag. This region of a database file
  569. ** never contains valid data anyhow. So avoid doing such a read here.
  570. **
  571. ** UPDATE: It also contains an assert() verifying that each call
  572. ** to the xRead() method reads less than 128KB of data.
  573. */
  574. const int isDb = (flags&SQLITE_OPEN_MAIN_DB);
  575. i64 iOff;
  576. memset(pWrapper->zData, 0, pWrapper->nData);
  577. for(iOff=0; iOff<pWrapper->iSize; iOff += 512){
  578. int nRead = pWrapper->iSize - (int)iOff;
  579. if( nRead>512 ) nRead = 512;
  580. if( isDb && iOff==PENDING_BYTE ) continue;
  581. rc = sqlite3OsRead(pReal, &pWrapper->zData[iOff], nRead, iOff);
  582. }
  583. }else{
  584. rc = SQLITE_NOMEM;
  585. }
  586. }
  587. if( rc!=SQLITE_OK && pWrapper->pMethod ){
  588. sqlite3OsClose(pFile);
  589. }
  590. return rc;
  591. }
  592. static int cfDelete(sqlite3_vfs *pCfVfs, const char *zPath, int dirSync){
  593. sqlite3_vfs *pVfs = (sqlite3_vfs *)pCfVfs->pAppData;
  594. return pVfs->xDelete(pVfs, zPath, dirSync);
  595. }
  596. static int cfAccess(
  597. sqlite3_vfs *pCfVfs,
  598. const char *zPath,
  599. int flags,
  600. int *pResOut
  601. ){
  602. sqlite3_vfs *pVfs = (sqlite3_vfs *)pCfVfs->pAppData;
  603. return pVfs->xAccess(pVfs, zPath, flags, pResOut);
  604. }
  605. static int cfFullPathname(
  606. sqlite3_vfs *pCfVfs,
  607. const char *zPath,
  608. int nPathOut,
  609. char *zPathOut
  610. ){
  611. sqlite3_vfs *pVfs = (sqlite3_vfs *)pCfVfs->pAppData;
  612. return pVfs->xFullPathname(pVfs, zPath, nPathOut, zPathOut);
  613. }
  614. static void *cfDlOpen(sqlite3_vfs *pCfVfs, const char *zPath){
  615. sqlite3_vfs *pVfs = (sqlite3_vfs *)pCfVfs->pAppData;
  616. return pVfs->xDlOpen(pVfs, zPath);
  617. }
  618. static void cfDlError(sqlite3_vfs *pCfVfs, int nByte, char *zErrMsg){
  619. sqlite3_vfs *pVfs = (sqlite3_vfs *)pCfVfs->pAppData;
  620. pVfs->xDlError(pVfs, nByte, zErrMsg);
  621. }
  622. static void (*cfDlSym(sqlite3_vfs *pCfVfs, void *pH, const char *zSym))(void){
  623. sqlite3_vfs *pVfs = (sqlite3_vfs *)pCfVfs->pAppData;
  624. return pVfs->xDlSym(pVfs, pH, zSym);
  625. }
  626. static void cfDlClose(sqlite3_vfs *pCfVfs, void *pHandle){
  627. sqlite3_vfs *pVfs = (sqlite3_vfs *)pCfVfs->pAppData;
  628. pVfs->xDlClose(pVfs, pHandle);
  629. }
  630. static int cfRandomness(sqlite3_vfs *pCfVfs, int nByte, char *zBufOut){
  631. sqlite3_vfs *pVfs = (sqlite3_vfs *)pCfVfs->pAppData;
  632. return pVfs->xRandomness(pVfs, nByte, zBufOut);
  633. }
  634. static int cfSleep(sqlite3_vfs *pCfVfs, int nMicro){
  635. sqlite3_vfs *pVfs = (sqlite3_vfs *)pCfVfs->pAppData;
  636. return pVfs->xSleep(pVfs, nMicro);
  637. }
  638. static int cfCurrentTime(sqlite3_vfs *pCfVfs, double *pTimeOut){
  639. sqlite3_vfs *pVfs = (sqlite3_vfs *)pCfVfs->pAppData;
  640. return pVfs->xCurrentTime(pVfs, pTimeOut);
  641. }
  642. static int processDevSymArgs(
  643. Tcl_Interp *interp,
  644. int objc,
  645. Tcl_Obj *CONST objv[],
  646. int *piDeviceChar,
  647. int *piSectorSize
  648. ){
  649. struct DeviceFlag {
  650. char *zName;
  651. int iValue;
  652. } aFlag[] = {
  653. { "atomic", SQLITE_IOCAP_ATOMIC },
  654. { "atomic512", SQLITE_IOCAP_ATOMIC512 },
  655. { "atomic1k", SQLITE_IOCAP_ATOMIC1K },
  656. { "atomic2k", SQLITE_IOCAP_ATOMIC2K },
  657. { "atomic4k", SQLITE_IOCAP_ATOMIC4K },
  658. { "atomic8k", SQLITE_IOCAP_ATOMIC8K },
  659. { "atomic16k", SQLITE_IOCAP_ATOMIC16K },
  660. { "atomic32k", SQLITE_IOCAP_ATOMIC32K },
  661. { "atomic64k", SQLITE_IOCAP_ATOMIC64K },
  662. { "sequential", SQLITE_IOCAP_SEQUENTIAL },
  663. { "safe_append", SQLITE_IOCAP_SAFE_APPEND },
  664. { "powersafe_overwrite", SQLITE_IOCAP_POWERSAFE_OVERWRITE },
  665. { 0, 0 }
  666. };
  667. int i;
  668. int iDc = 0;
  669. int iSectorSize = 0;
  670. int setSectorsize = 0;
  671. int setDeviceChar = 0;
  672. for(i=0; i<objc; i+=2){
  673. int nOpt;
  674. char *zOpt = Tcl_GetStringFromObj(objv[i], &nOpt);
  675. if( (nOpt>11 || nOpt<2 || strncmp("-sectorsize", zOpt, nOpt))
  676. && (nOpt>16 || nOpt<2 || strncmp("-characteristics", zOpt, nOpt))
  677. ){
  678. Tcl_AppendResult(interp,
  679. "Bad option: \"", zOpt,
  680. "\" - must be \"-characteristics\" or \"-sectorsize\"", 0
  681. );
  682. return TCL_ERROR;
  683. }
  684. if( i==objc-1 ){
  685. Tcl_AppendResult(interp, "Option requires an argument: \"", zOpt, "\"",0);
  686. return TCL_ERROR;
  687. }
  688. if( zOpt[1]=='s' ){
  689. if( Tcl_GetIntFromObj(interp, objv[i+1], &iSectorSize) ){
  690. return TCL_ERROR;
  691. }
  692. setSectorsize = 1;
  693. }else{
  694. int j;
  695. Tcl_Obj **apObj;
  696. int nObj;
  697. if( Tcl_ListObjGetElements(interp, objv[i+1], &nObj, &apObj) ){
  698. return TCL_ERROR;
  699. }
  700. for(j=0; j<nObj; j++){
  701. int rc;
  702. int iChoice;
  703. Tcl_Obj *pFlag = Tcl_DuplicateObj(apObj[j]);
  704. Tcl_IncrRefCount(pFlag);
  705. Tcl_UtfToLower(Tcl_GetString(pFlag));
  706. rc = Tcl_GetIndexFromObjStruct(
  707. interp, pFlag, aFlag, sizeof(aFlag[0]), "no such flag", 0, &iChoice
  708. );
  709. Tcl_DecrRefCount(pFlag);
  710. if( rc ){
  711. return TCL_ERROR;
  712. }
  713. iDc |= aFlag[iChoice].iValue;
  714. }
  715. setDeviceChar = 1;
  716. }
  717. }
  718. if( setDeviceChar ){
  719. *piDeviceChar = iDc;
  720. }
  721. if( setSectorsize ){
  722. *piSectorSize = iSectorSize;
  723. }
  724. return TCL_OK;
  725. }
  726. /*
  727. ** tclcmd: sqlite_crash_enable ENABLE
  728. **
  729. ** Parameter ENABLE must be a boolean value. If true, then the "crash"
  730. ** vfs is added to the system. If false, it is removed.
  731. */
  732. static int crashEnableCmd(
  733. void * clientData,
  734. Tcl_Interp *interp,
  735. int objc,
  736. Tcl_Obj *CONST objv[]
  737. ){
  738. int isEnable;
  739. static sqlite3_vfs crashVfs = {
  740. 2, /* iVersion */
  741. 0, /* szOsFile */
  742. 0, /* mxPathname */
  743. 0, /* pNext */
  744. "crash", /* zName */
  745. 0, /* pAppData */
  746. cfOpen, /* xOpen */
  747. cfDelete, /* xDelete */
  748. cfAccess, /* xAccess */
  749. cfFullPathname, /* xFullPathname */
  750. cfDlOpen, /* xDlOpen */
  751. cfDlError, /* xDlError */
  752. cfDlSym, /* xDlSym */
  753. cfDlClose, /* xDlClose */
  754. cfRandomness, /* xRandomness */
  755. cfSleep, /* xSleep */
  756. cfCurrentTime, /* xCurrentTime */
  757. 0, /* xGetlastError */
  758. 0, /* xCurrentTimeInt64 */
  759. };
  760. if( objc!=2 ){
  761. Tcl_WrongNumArgs(interp, 1, objv, "ENABLE");
  762. return TCL_ERROR;
  763. }
  764. if( Tcl_GetBooleanFromObj(interp, objv[1], &isEnable) ){
  765. return TCL_ERROR;
  766. }
  767. if( (isEnable && crashVfs.pAppData) || (!isEnable && !crashVfs.pAppData) ){
  768. return TCL_OK;
  769. }
  770. if( crashVfs.pAppData==0 ){
  771. sqlite3_vfs *pOriginalVfs = sqlite3_vfs_find(0);
  772. crashVfs.mxPathname = pOriginalVfs->mxPathname;
  773. crashVfs.pAppData = (void *)pOriginalVfs;
  774. crashVfs.szOsFile = sizeof(CrashFile) + pOriginalVfs->szOsFile;
  775. sqlite3_vfs_register(&crashVfs, 0);
  776. }else{
  777. crashVfs.pAppData = 0;
  778. sqlite3_vfs_unregister(&crashVfs);
  779. }
  780. return TCL_OK;
  781. }
  782. /*
  783. ** tclcmd: sqlite_crashparams ?OPTIONS? DELAY CRASHFILE
  784. **
  785. ** This procedure implements a TCL command that enables crash testing
  786. ** in testfixture. Once enabled, crash testing cannot be disabled.
  787. **
  788. ** Available options are "-characteristics" and "-sectorsize". Both require
  789. ** an argument. For -sectorsize, this is the simulated sector size in
  790. ** bytes. For -characteristics, the argument must be a list of io-capability
  791. ** flags to simulate. Valid flags are "atomic", "atomic512", "atomic1K",
  792. ** "atomic2K", "atomic4K", "atomic8K", "atomic16K", "atomic32K",
  793. ** "atomic64K", "sequential" and "safe_append".
  794. **
  795. ** Example:
  796. **
  797. ** sqlite_crashparams -sect 1024 -char {atomic sequential} ./test.db 1
  798. **
  799. */
  800. static int crashParamsObjCmd(
  801. void * clientData,
  802. Tcl_Interp *interp,
  803. int objc,
  804. Tcl_Obj *CONST objv[]
  805. ){
  806. int iDelay;
  807. const char *zCrashFile;
  808. int nCrashFile, iDc, iSectorSize;
  809. iDc = -1;
  810. iSectorSize = -1;
  811. if( objc<3 ){
  812. Tcl_WrongNumArgs(interp, 1, objv, "?OPTIONS? DELAY CRASHFILE");
  813. goto error;
  814. }
  815. zCrashFile = Tcl_GetStringFromObj(objv[objc-1], &nCrashFile);
  816. if( nCrashFile>=sizeof(g.zCrashFile) ){
  817. Tcl_AppendResult(interp, "Filename is too long: \"", zCrashFile, "\"", 0);
  818. goto error;
  819. }
  820. if( Tcl_GetIntFromObj(interp, objv[objc-2], &iDelay) ){
  821. goto error;
  822. }
  823. if( processDevSymArgs(interp, objc-3, &objv[1], &iDc, &iSectorSize) ){
  824. return TCL_ERROR;
  825. }
  826. if( iDc>=0 ){
  827. g.iDeviceCharacteristics = iDc;
  828. }
  829. if( iSectorSize>=0 ){
  830. g.iSectorSize = iSectorSize;
  831. }
  832. g.iCrash = iDelay;
  833. memcpy(g.zCrashFile, zCrashFile, nCrashFile+1);
  834. sqlite3CrashTestEnable = 1;
  835. return TCL_OK;
  836. error:
  837. return TCL_ERROR;
  838. }
  839. static int devSymObjCmd(
  840. void * clientData,
  841. Tcl_Interp *interp,
  842. int objc,
  843. Tcl_Obj *CONST objv[]
  844. ){
  845. void devsym_register(int iDeviceChar, int iSectorSize);
  846. int iDc = -1;
  847. int iSectorSize = -1;
  848. if( processDevSymArgs(interp, objc-1, &objv[1], &iDc, &iSectorSize) ){
  849. return TCL_ERROR;
  850. }
  851. devsym_register(iDc, iSectorSize);
  852. return TCL_OK;
  853. }
  854. /*
  855. ** tclcmd: register_jt_vfs ?-default? PARENT-VFS
  856. */
  857. static int jtObjCmd(
  858. void * clientData,
  859. Tcl_Interp *interp,
  860. int objc,
  861. Tcl_Obj *CONST objv[]
  862. ){
  863. int jt_register(char *, int);
  864. char *zParent = 0;
  865. if( objc!=2 && objc!=3 ){
  866. Tcl_WrongNumArgs(interp, 1, objv, "?-default? PARENT-VFS");
  867. return TCL_ERROR;
  868. }
  869. zParent = Tcl_GetString(objv[1]);
  870. if( objc==3 ){
  871. if( strcmp(zParent, "-default") ){
  872. Tcl_AppendResult(interp,
  873. "bad option \"", zParent, "\": must be -default", 0
  874. );
  875. return TCL_ERROR;
  876. }
  877. zParent = Tcl_GetString(objv[2]);
  878. }
  879. if( !(*zParent) ){
  880. zParent = 0;
  881. }
  882. if( jt_register(zParent, objc==3) ){
  883. Tcl_AppendResult(interp, "Error in jt_register", 0);
  884. return TCL_ERROR;
  885. }
  886. return TCL_OK;
  887. }
  888. /*
  889. ** tclcmd: unregister_jt_vfs
  890. */
  891. static int jtUnregisterObjCmd(
  892. void * clientData,
  893. Tcl_Interp *interp,
  894. int objc,
  895. Tcl_Obj *CONST objv[]
  896. ){
  897. void jt_unregister(void);
  898. if( objc!=1 ){
  899. Tcl_WrongNumArgs(interp, 1, objv, "");
  900. return TCL_ERROR;
  901. }
  902. jt_unregister();
  903. return TCL_OK;
  904. }
  905. #endif /* SQLITE_OMIT_DISKIO */
  906. /*
  907. ** This procedure registers the TCL procedures defined in this file.
  908. */
  909. int Sqlitetest6_Init(Tcl_Interp *interp){
  910. #ifndef SQLITE_OMIT_DISKIO
  911. Tcl_CreateObjCommand(interp, "sqlite3_crash_enable", crashEnableCmd, 0, 0);
  912. Tcl_CreateObjCommand(interp, "sqlite3_crashparams", crashParamsObjCmd, 0, 0);
  913. Tcl_CreateObjCommand(interp, "sqlite3_simulate_device", devSymObjCmd, 0, 0);
  914. Tcl_CreateObjCommand(interp, "register_jt_vfs", jtObjCmd, 0, 0);
  915. Tcl_CreateObjCommand(interp, "unregister_jt_vfs", jtUnregisterObjCmd, 0, 0);
  916. #endif
  917. return TCL_OK;
  918. }
  919. #endif /* SQLITE_TEST */