Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Improvements to the logging that occurs on an antivirus I/O retry. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | av-defense |
Files: | files | file ages | folders |
SHA1: |
ff0ff75c3559f5bbe29c73204cc8ff1c |
User & Date: | drh 2011-07-12 13:51:05.210 |
Context
2011-07-12
| ||
14:02 | Revise logic in winDelete to check the file prior to attempting to delete it. (Closed-Leaf check-in: 36f11acc53 user: mistachkin tags: av-defense) | |
13:51 | Improvements to the logging that occurs on an antivirus I/O retry. (check-in: ff0ff75c35 user: drh tags: av-defense) | |
11:04 | Update the anti-virus retry logic for DeleteFile(). Invoke sqlite3_log() for each anti-virus retry. Make the retry delay configurable at compile-time. (check-in: 89f1848d7f user: drh tags: av-defense) | |
Changes
Changes to src/os_win.c.
︙ | ︙ | |||
423 424 425 426 427 428 429 | static int retryIoerr(int *pnRetry){ DWORD e; if( *pnRetry>=SQLITE_WIN32_IOERR_RETRY ){ return 0; } e = GetLastError(); if( e==ERROR_LOCK_VIOLATION || e==ERROR_SHARING_VIOLATION ){ | | < < < > > > > > > > > > > > > | 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 | static int retryIoerr(int *pnRetry){ DWORD e; if( *pnRetry>=SQLITE_WIN32_IOERR_RETRY ){ return 0; } e = GetLastError(); if( e==ERROR_LOCK_VIOLATION || e==ERROR_SHARING_VIOLATION ){ Sleep(SQLITE_WIN32_IOERR_RETRY_DELAY*(1+*pnRetry)); ++*pnRetry; return 1; } return 0; } /* ** Log a I/O error retry episode. */ static void logIoerr(int nRetry){ if( nRetry ){ sqlite3_log(SQLITE_IOERR, "delayed %dms for lock/sharing conflict", SQLITE_WIN32_IOERR_RETRY_DELAY*nRetry*(nRetry+1)/2 ); } } #if SQLITE_OS_WINCE /************************************************************************* ** This section contains code for WinCE only. */ /* ** WindowsCE does not have a localtime() function. So create a |
︙ | ︙ | |||
865 866 867 868 869 870 871 872 873 874 875 876 877 878 | return SQLITE_FULL; } while( !ReadFile(pFile->h, pBuf, amt, &nRead, 0) ){ if( retryIoerr(&nRetry) ) continue; pFile->lastErrno = GetLastError(); return winLogError(SQLITE_IOERR_READ, "winRead", pFile->zPath); } if( nRead<(DWORD)amt ){ /* Unread parts of the buffer must be zero-filled */ memset(&((char*)pBuf)[nRead], 0, amt-nRead); return SQLITE_IOERR_SHORT_READ; } return SQLITE_OK; | > | 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 | return SQLITE_FULL; } while( !ReadFile(pFile->h, pBuf, amt, &nRead, 0) ){ if( retryIoerr(&nRetry) ) continue; pFile->lastErrno = GetLastError(); return winLogError(SQLITE_IOERR_READ, "winRead", pFile->zPath); } logIoerr(nRetry); if( nRead<(DWORD)amt ){ /* Unread parts of the buffer must be zero-filled */ memset(&((char*)pBuf)[nRead], 0, amt-nRead); return SQLITE_IOERR_SHORT_READ; } return SQLITE_OK; |
︙ | ︙ | |||
886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 | sqlite3_file *id, /* File to write into */ const void *pBuf, /* The bytes to be written */ int amt, /* Number of bytes to write */ sqlite3_int64 offset /* Offset into the file to begin writing at */ ){ int rc; /* True if error has occured, else false */ winFile *pFile = (winFile*)id; /* File handle */ assert( amt>0 ); assert( pFile ); SimulateIOError(return SQLITE_IOERR_WRITE); SimulateDiskfullError(return SQLITE_FULL); OSTRACE(("WRITE %d lock=%d\n", pFile->h, pFile->locktype)); rc = seekWinFile(pFile, offset); if( rc==0 ){ u8 *aRem = (u8 *)pBuf; /* Data yet to be written */ int nRem = amt; /* Number of bytes yet to be written */ DWORD nWrite; /* Bytes written by each WriteFile() call */ | > < | 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 | sqlite3_file *id, /* File to write into */ const void *pBuf, /* The bytes to be written */ int amt, /* Number of bytes to write */ sqlite3_int64 offset /* Offset into the file to begin writing at */ ){ int rc; /* True if error has occured, else false */ winFile *pFile = (winFile*)id; /* File handle */ int nRetry = 0; /* Number of retries */ assert( amt>0 ); assert( pFile ); SimulateIOError(return SQLITE_IOERR_WRITE); SimulateDiskfullError(return SQLITE_FULL); OSTRACE(("WRITE %d lock=%d\n", pFile->h, pFile->locktype)); rc = seekWinFile(pFile, offset); if( rc==0 ){ u8 *aRem = (u8 *)pBuf; /* Data yet to be written */ int nRem = amt; /* Number of bytes yet to be written */ DWORD nWrite; /* Bytes written by each WriteFile() call */ while( nRem>0 ){ if( !WriteFile(pFile->h, aRem, nRem, &nWrite, 0) ){ if( retryIoerr(&nRetry) ) continue; break; } if( nWrite<=0 ) break; |
︙ | ︙ | |||
922 923 924 925 926 927 928 929 930 931 932 933 934 935 | if( rc ){ if( ( pFile->lastErrno==ERROR_HANDLE_DISK_FULL ) || ( pFile->lastErrno==ERROR_DISK_FULL )){ return SQLITE_FULL; } return winLogError(SQLITE_IOERR_WRITE, "winWrite", pFile->zPath); } return SQLITE_OK; } /* ** Truncate an open file to a specified size */ | > > | 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 | if( rc ){ if( ( pFile->lastErrno==ERROR_HANDLE_DISK_FULL ) || ( pFile->lastErrno==ERROR_DISK_FULL )){ return SQLITE_FULL; } return winLogError(SQLITE_IOERR_WRITE, "winWrite", pFile->zPath); }else{ logIoerr(nRetry); } return SQLITE_OK; } /* ** Truncate an open file to a specified size */ |
︙ | ︙ | |||
2382 2383 2384 2385 2386 2387 2388 | ** it's important to not reference them for WINCE builds. */ #if SQLITE_OS_WINCE==0 }else{ while( (rc = DeleteFileW(zConverted))!=0 || retryIoerr(&cnt) ){} #endif } | > | > > > | 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 2412 | ** it's important to not reference them for WINCE builds. */ #if SQLITE_OS_WINCE==0 }else{ while( (rc = DeleteFileW(zConverted))!=0 || retryIoerr(&cnt) ){} #endif } if( rc ){ rc = winLogError(SQLITE_IOERR_DELETE, "winDelete", zFilename); }else{ logIoerr(cnt); } free(zConverted); OSTRACE(("DELETE \"%s\" %s\n", zFilename, (rc ? "failed" : "ok" ))); return rc; } /* ** Check the existance and status of a file. |
︙ | ︙ |
Changes to test/win32lock.test.
︙ | ︙ | |||
16 17 18 19 20 21 22 23 24 25 26 27 28 29 | if {$tcl_platform(platform)!="windows"} return set testdir [file dirname $argv0] source $testdir/tester.tcl set testprefix win32lock do_test win32lock-1.1 { db eval { PRAGMA cache_size=10; CREATE TABLE t1(x,y); INSERT INTO t1 VALUES(1,randomblob(100000)); INSERT INTO t1 VALUES(2,randomblob(50000)); INSERT INTO t1 VALUES(3,randomblob(25000)); | > > > > > > > > | 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | if {$tcl_platform(platform)!="windows"} return set testdir [file dirname $argv0] source $testdir/tester.tcl set testprefix win32lock db close sqlite3_shutdown test_sqlite3_log xLog proc xLog {error_code msg} { lappend ::log $msg } sqlite3 db test.db do_test win32lock-1.1 { db eval { PRAGMA cache_size=10; CREATE TABLE t1(x,y); INSERT INTO t1 VALUES(1,randomblob(100000)); INSERT INTO t1 VALUES(2,randomblob(50000)); INSERT INTO t1 VALUES(3,randomblob(25000)); |
︙ | ︙ | |||
45 46 47 48 49 50 51 52 53 54 55 | set ::msg } {disk I/O error} break } else { do_test win32lock-1.2-$delay1 { set ::msg } {1 100000 2 50000 3 25000 4 12500} incr delay1 50 } } sqlite3_test_control_pending_byte $old_pending_byte | > > > > > > > | > > | 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 | set ::msg } {disk I/O error} break } else { do_test win32lock-1.2-$delay1 { set ::msg } {1 100000 2 50000 3 25000 4 12500} if {$::log!=""} { do_test win32lock-1.2-$delay1-log1 { regsub {\d+} $::log # x set x } {{delayed #ms for lock/sharing conflict}} } incr delay1 50 } set ::log {} } sqlite3_test_control_pending_byte $old_pending_byte sqlite3_shutdown test_sqlite3_log sqlite3_initialize finish_test |