/ Check-in [f71dfee0]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Fix an error in the previous commit on this branch.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | readonly-wal-recovery
Files: files | file ages | folders
SHA3-256:f71dfee06ce1e0eee760cfca19482bdec7729d6c7d28f10f4cfd21e1f92a04b0
User & Date: dan 2017-10-26 17:34:50
Context
2017-11-01
06:59
Fix a race condition in os_unix.c that might allow a client to use a *-shm file corrupted by a power failure if another client fails between locking the *-shm file and truncating it to zero bytes. check-in: d655bfab user: dan tags: readonly-wal-recovery
2017-10-26
17:34
Fix an error in the previous commit on this branch. check-in: f71dfee0 user: dan tags: readonly-wal-recovery
17:05
Instead of extra locks, use F_GETLK to ensure that readonly_shm clients cannot connect to a wal-mode database if there are no writers. check-in: 5492f457 user: dan tags: readonly-wal-recovery
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/os_unix.c.

4397
4398
4399
4400
4401
4402
4403
4404
4405
4406
4407
4408
4409
4410
4411
      rc = SQLITE_OK;
      if( pShmNode->isReadonly ){
        struct flock lock;
        lock.l_whence = SEEK_SET;
        lock.l_start = UNIX_SHM_DMS;
        lock.l_len = 1;
        lock.l_type = F_WRLCK;
        if( osFcntl(pShmNode->h, F_GETLK, &lockInfo)!=0 ) {
          rc = SQLITE_IOERR_LOCK;
        }else if( lock.l_type==F_UNLCK ){
          rc = SQLITE_CANTOPEN_DIRTYWAL;
        }
      }else if( unixShmSystemLock(pDbFd, F_WRLCK, UNIX_SHM_DMS, 1)==SQLITE_OK ){
        if( robust_ftruncate(pShmNode->h, 0) ){
          rc = unixLogError(SQLITE_IOERR_SHMOPEN, "ftruncate", zShmFilename);







|







4397
4398
4399
4400
4401
4402
4403
4404
4405
4406
4407
4408
4409
4410
4411
      rc = SQLITE_OK;
      if( pShmNode->isReadonly ){
        struct flock lock;
        lock.l_whence = SEEK_SET;
        lock.l_start = UNIX_SHM_DMS;
        lock.l_len = 1;
        lock.l_type = F_WRLCK;
        if( osFcntl(pShmNode->h, F_GETLK, &lock)!=0 ) {
          rc = SQLITE_IOERR_LOCK;
        }else if( lock.l_type==F_UNLCK ){
          rc = SQLITE_CANTOPEN_DIRTYWAL;
        }
      }else if( unixShmSystemLock(pDbFd, F_WRLCK, UNIX_SHM_DMS, 1)==SQLITE_OK ){
        if( robust_ftruncate(pShmNode->h, 0) ){
          rc = unixLogError(SQLITE_IOERR_SHMOPEN, "ftruncate", zShmFilename);

Changes to test/walro.test.

97
98
99
100
101
102
103

104
105
106
107

108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
...
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
  do_test 1.1.13  { sql2 "INSERT INTO t1 VALUES('i', 'j')" } {}

  do_test 1.2.1 {
    code2 { db2 close }
    code1 { db close }
    list [file exists test.db-wal] [file exists test.db-shm]
  } {1 1}

  do_test 1.2.2 {
    code1 { sqlite3 db file:test.db?readonly_shm=1 }
    sql1 { SELECT * FROM t1 }
  } {a b c d e f g h i j}


  do_test 1.2.3 {
    code1 { db close }
    file attributes test.db-shm -permissions rw-r--r--
    hexio_write test.db-shm 0 01020304 
    file attributes test.db-shm -permissions r--r--r--
    code1 { sqlite3 db file:test.db?readonly_shm=1 }
    csql1 { SELECT * FROM t1 }
  } {1 {attempt to write a readonly database}}
  do_test 1.2.4 {
    code1 { sqlite3_extended_errcode db } 
  } {SQLITE_READONLY_RECOVERY}

  do_test 1.2.5 {
    file attributes test.db-shm -permissions rw-r--r--
    code2 { sqlite3 db2 test.db }
    sql2 "SELECT * FROM t1" 
  } {a b c d e f g h i j}
  file attributes test.db-shm -permissions r--r--r--
................................................................................
  } {1 {unable to open database file}}
  do_test 1.3.2.3 {
    code1 { db close }
    close [open test.db-shm w]
    file attributes test.db-shm -permissions r--r--r--
    code1 { sqlite3 db file:test.db?readonly_shm=1 }
    csql1 { SELECT * FROM t1 }
  } {1 {attempt to write a readonly database}}
  do_test 1.3.2.4 {
    code1 { sqlite3_extended_errcode db } 
  } {SQLITE_READONLY_RECOVERY}

  #-----------------------------------------------------------------------
  # Test cases 1.4.* check that checkpoints and log wraps don't prevent
  # read-only connections from reading the database.
  do_test 1.4.1 {
    code1 { db close }
    forcedelete test.db-shm







>


|
<
>








|


|







 







|


|







97
98
99
100
101
102
103
104
105
106
107

108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
...
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
  do_test 1.1.13  { sql2 "INSERT INTO t1 VALUES('i', 'j')" } {}

  do_test 1.2.1 {
    code2 { db2 close }
    code1 { db close }
    list [file exists test.db-wal] [file exists test.db-shm]
  } {1 1}

  do_test 1.2.2 {
    code1 { sqlite3 db file:test.db?readonly_shm=1 }
    list [catch { sql1 { SELECT * FROM t1 } } msg] $msg

  } {1 {unable to open database file}}

  do_test 1.2.3 {
    code1 { db close }
    file attributes test.db-shm -permissions rw-r--r--
    hexio_write test.db-shm 0 01020304 
    file attributes test.db-shm -permissions r--r--r--
    code1 { sqlite3 db file:test.db?readonly_shm=1 }
    csql1 { SELECT * FROM t1 }
  } {1 {unable to open database file}}
  do_test 1.2.4 {
    code1 { sqlite3_extended_errcode db } 
  } {SQLITE_CANTOPEN}

  do_test 1.2.5 {
    file attributes test.db-shm -permissions rw-r--r--
    code2 { sqlite3 db2 test.db }
    sql2 "SELECT * FROM t1" 
  } {a b c d e f g h i j}
  file attributes test.db-shm -permissions r--r--r--
................................................................................
  } {1 {unable to open database file}}
  do_test 1.3.2.3 {
    code1 { db close }
    close [open test.db-shm w]
    file attributes test.db-shm -permissions r--r--r--
    code1 { sqlite3 db file:test.db?readonly_shm=1 }
    csql1 { SELECT * FROM t1 }
  } {1 {unable to open database file}}
  do_test 1.3.2.4 {
    code1 { sqlite3_extended_errcode db } 
  } {SQLITE_CANTOPEN}

  #-----------------------------------------------------------------------
  # Test cases 1.4.* check that checkpoints and log wraps don't prevent
  # read-only connections from reading the database.
  do_test 1.4.1 {
    code1 { db close }
    forcedelete test.db-shm