Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(10)

Side by Side Diff: third_party/sqlite/patches/0007-backport-SQLite-os-intercept-changes.patch

Issue 885473002: [sql] Rewrite sqlite patching "system". (Closed) Base URL: http://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 From 0cd243b0f2f7e2b85e30a1bb20f9bd41e2779774 Mon Sep 17 00:00:00 2001
2 From: Scott Hess <shess@chromium.org>
3 Date: Tue, 16 Dec 2014 13:06:33 -0800
4 Subject: [PATCH 07/24] [backport] SQLite os-intercept changes.
5
6 This is a backport of the following SQLite changes to experiment with
7 implementing WebDatabase with an unpatched SQLite:
8
9 1. http://sqlite.org/src/ci/9109128cb5
10 2. http://sqlite.org/src/ci/713b1b7dc1
11 3. http://sqlite.org/src/ci/8d1b5c3ac0
12 4. http://sqlite.org/src/ci/6b236069e1
13 5. http://sqlite.org/src/ci/880b51150a
14
15 BUG=22208
16 ---
17 third_party/sqlite/src/src/os_unix.c | 187 +++++++++++++++----------------
18 third_party/sqlite/src/test/syscall.test | 2 +-
19 2 files changed, 93 insertions(+), 96 deletions(-)
20
21 diff --git a/third_party/sqlite/src/src/os_unix.c b/third_party/sqlite/src/src/o s_unix.c
22 index 766b52a..77ffd8a 100644
23 --- a/third_party/sqlite/src/src/os_unix.c
24 +++ b/third_party/sqlite/src/src/os_unix.c
25 @@ -204,7 +204,6 @@ struct unixFile {
26 sqlite3_io_methods const *pMethod; /* Always the first entry */
27 unixInodeInfo *pInode; /* Info about locks on this inode */
28 int h; /* The file descriptor */
29 - int dirfd; /* File descriptor for the directory */
30 unsigned char eFileLock; /* The type of lock held on this fd */
31 unsigned char ctrlFlags; /* Behavioral bits. UNIXFILE_* flags */
32 int lastErrno; /* The unix errno from last I/O error */
33 @@ -248,6 +247,7 @@ struct unixFile {
34 */
35 #define UNIXFILE_EXCL 0x01 /* Connections from one process only */
36 #define UNIXFILE_RDONLY 0x02 /* Connection is read only */
37 +#define UNIXFILE_DIRSYNC 0x04 /* Directory sync needed */
38
39 /*
40 ** Include code that is common to all os_*.c files
41 @@ -281,6 +281,9 @@ struct unixFile {
42 #define threadid 0
43 #endif
44
45 +/* Forward reference */
46 +static int openDirectory(const char*, int*);
47 +
48 /*
49 ** Many system calls are accessed through pointer-to-functions so that
50 ** they may be overridden at runtime to facilitate fault injection during
51 @@ -377,6 +380,12 @@ static struct unix_syscall {
52 #endif
53 #define osFallocate ((int(*)(int,off_t,off_t))aSyscall[15].pCurrent)
54
55 + { "unlink", (sqlite3_syscall_ptr)unlink, 0 },
56 +#define osUnlink ((int(*)(const char*))aSyscall[16].pCurrent)
57 +
58 + { "openDirectory", (sqlite3_syscall_ptr)openDirectory, 0 },
59 +#define osOpenDirectory ((int(*)(const char*,int*))aSyscall[17].pCurrent)
60 +
61 }; /* End of the overrideable system calls */
62
63 /*
64 @@ -1731,10 +1740,6 @@ static int unixUnlock(sqlite3_file *id, int eFileLock){
65 */
66 static int closeUnixFile(sqlite3_file *id){
67 unixFile *pFile = (unixFile*)id;
68 - if( pFile->dirfd>=0 ){
69 - robust_close(pFile, pFile->dirfd, __LINE__);
70 - pFile->dirfd=-1;
71 - }
72 if( pFile->h>=0 ){
73 robust_close(pFile, pFile->h, __LINE__);
74 pFile->h = -1;
75 @@ -1742,7 +1747,7 @@ static int closeUnixFile(sqlite3_file *id){
76 #if OS_VXWORKS
77 if( pFile->pId ){
78 if( pFile->isDelete ){
79 - unlink(pFile->pId->zCanonicalName);
80 + osUnlink(pFile->pId->zCanonicalName);
81 }
82 vxworksReleaseFileId(pFile->pId);
83 pFile->pId = 0;
84 @@ -1989,7 +1994,7 @@ static int dotlockUnlock(sqlite3_file *id, int eFileLock) {
85
86 /* To fully unlock the database, delete the lock file */
87 assert( eFileLock==NO_LOCK );
88 - if( unlink(zLockFile) ){
89 + if( osUnlink(zLockFile) ){
90 int rc = 0;
91 int tErrno = errno;
92 if( ENOENT != tErrno ){
93 @@ -3226,6 +3231,50 @@ static int full_fsync(int fd, int fullSync, int dataOnly) {
94 }
95
96 /*
97 +** Open a file descriptor to the directory containing file zFilename.
98 +** If successful, *pFd is set to the opened file descriptor and
99 +** SQLITE_OK is returned. If an error occurs, either SQLITE_NOMEM
100 +** or SQLITE_CANTOPEN is returned and *pFd is set to an undefined
101 +** value.
102 +**
103 +** The directory file descriptor is used for only one thing - to
104 +** fsync() a directory to make sure file creation and deletion events
105 +** are flushed to disk. Such fsyncs are not needed on newer
106 +** journaling filesystems, but are required on older filesystems.
107 +**
108 +** This routine can be overridden using the xSetSysCall interface.
109 +** The ability to override this routine was added in support of the
110 +** chromium sandbox. Opening a directory is a security risk (we are
111 +** told) so making it overrideable allows the chromium sandbox to
112 +** replace this routine with a harmless no-op. To make this routine
113 +** a no-op, replace it with a stub that returns SQLITE_OK but leaves
114 +** *pFd set to a negative number.
115 +**
116 +** If SQLITE_OK is returned, the caller is responsible for closing
117 +** the file descriptor *pFd using close().
118 +*/
119 +static int openDirectory(const char *zFilename, int *pFd){
120 + int ii;
121 + int fd = -1;
122 + char zDirname[MAX_PATHNAME+1];
123 +
124 + sqlite3_snprintf(MAX_PATHNAME, zDirname, "%s", zFilename);
125 + for(ii=(int)strlen(zDirname); ii>1 && zDirname[ii]!='/'; ii--);
126 + if( ii>0 ){
127 + zDirname[ii] = '\0';
128 + fd = robust_open(zDirname, O_RDONLY|O_BINARY, 0);
129 + if( fd>=0 ){
130 +#ifdef FD_CLOEXEC
131 + osFcntl(fd, F_SETFD, osFcntl(fd, F_GETFD, 0) | FD_CLOEXEC);
132 +#endif
133 + OSTRACE(("OPENDIR %-3d %s\n", fd, zDirname));
134 + }
135 + }
136 + *pFd = fd;
137 + return (fd>=0?SQLITE_OK:unixLogError(SQLITE_CANTOPEN_BKPT, "open", zDirname)) ;
138 +}
139 +
140 +/*
141 ** Make sure all writes to a particular file are committed to disk.
142 **
143 ** If dataOnly==0 then both the file itself and its metadata (file
144 @@ -3265,28 +3314,23 @@ static int unixSync(sqlite3_file *id, int flags){
145 pFile->lastErrno = errno;
146 return unixLogError(SQLITE_IOERR_FSYNC, "full_fsync", pFile->zPath);
147 }
148 - if( pFile->dirfd>=0 ){
149 - OSTRACE(("DIRSYNC %-3d (have_fullfsync=%d fullsync=%d)\n", pFile->dirfd,
150 +
151 + /* Also fsync the directory containing the file if the DIRSYNC flag
152 + ** is set. This is a one-time occurrance. Many systems (examples: AIX)
153 + ** are unable to fsync a directory, so ignore errors on the fsync.
154 + */
155 + if( pFile->ctrlFlags & UNIXFILE_DIRSYNC ){
156 + int dirfd;
157 + OSTRACE(("DIRSYNC %s (have_fullfsync=%d fullsync=%d)\n", pFile->zPath,
158 HAVE_FULLFSYNC, isFullsync));
159 -#ifndef SQLITE_DISABLE_DIRSYNC
160 - /* The directory sync is only attempted if full_fsync is
161 - ** turned off or unavailable. If a full_fsync occurred above,
162 - ** then the directory sync is superfluous.
163 - */
164 - if( (!HAVE_FULLFSYNC || !isFullsync) && full_fsync(pFile->dirfd,0,0) ){
165 - /*
166 - ** We have received multiple reports of fsync() returning
167 - ** errors when applied to directories on certain file systems.
168 - ** A failed directory sync is not a big deal. So it seems
169 - ** better to ignore the error. Ticket #1657
170 - */
171 - /* pFile->lastErrno = errno; */
172 - /* return SQLITE_IOERR; */
173 + rc = osOpenDirectory(pFile->zPath, &dirfd);
174 + if( rc==SQLITE_OK && dirfd>=0 ){
175 + full_fsync(dirfd, 0, 0);
176 + robust_close(pFile, dirfd, __LINE__);
177 + }else if( rc==SQLITE_CANTOPEN ){
178 + rc = SQLITE_OK;
179 }
180 -#endif
181 - /* Only need to sync once, so close the directory when we are done */
182 - robust_close(pFile, pFile->dirfd, __LINE__);
183 - pFile->dirfd = -1;
184 + pFile->ctrlFlags &= ~UNIXFILE_DIRSYNC;
185 }
186 return rc;
187 }
188 @@ -4110,7 +4154,7 @@ static int unixShmUnmap(
189 assert( pShmNode->nRef>0 );
190 pShmNode->nRef--;
191 if( pShmNode->nRef==0 ){
192 - if( deleteFlag && pShmNode->h>=0 ) unlink(pShmNode->zFilename);
193 + if( deleteFlag && pShmNode->h>=0 ) osUnlink(pShmNode->zFilename);
194 unixShmPurge(pDbFd);
195 }
196 unixLeaveMutex();
197 @@ -4430,7 +4474,7 @@ void initUnixFile(sqlite3_file* file) {
198 int fillInUnixFile(
199 sqlite3_vfs *pVfs, /* Pointer to vfs object */
200 int h, /* Open file descriptor of file being opened */
201 - int dirfd, /* Directory file descriptor */
202 + int syncDir, /* True to sync directory on first sync */
203 sqlite3_file *pId, /* Write to the unixFile structure here */
204 const char *zFilename, /* Name of the file being opened */
205 int noLock, /* Omit locking if true */
206 @@ -4461,7 +4505,6 @@ int fillInUnixFile(
207
208 OSTRACE(("OPEN %-3d %s\n", h, zFilename));
209 pNew->h = h;
210 - pNew->dirfd = dirfd;
211 pNew->zPath = zFilename;
212 if( strcmp(pVfs->zName,"unix-excl")==0 ){
213 pNew->ctrlFlags = UNIXFILE_EXCL;
214 @@ -4471,6 +4514,9 @@ int fillInUnixFile(
215 if( isReadOnly ){
216 pNew->ctrlFlags |= UNIXFILE_RDONLY;
217 }
218 + if( syncDir ){
219 + pNew->ctrlFlags |= UNIXFILE_DIRSYNC;
220 + }
221
222 #if OS_VXWORKS
223 pNew->pId = vxworksFindFileId(zFilename);
224 @@ -4597,13 +4643,12 @@ int fillInUnixFile(
225 if( rc!=SQLITE_OK ){
226 if( h>=0 ) robust_close(pNew, h, __LINE__);
227 h = -1;
228 - unlink(zFilename);
229 + osUnlink(zFilename);
230 isDelete = 0;
231 }
232 pNew->isDelete = isDelete;
233 #endif
234 if( rc!=SQLITE_OK ){
235 - if( dirfd>=0 ) robust_close(pNew, dirfd, __LINE__);
236 if( h>=0 ) robust_close(pNew, h, __LINE__);
237 }else{
238 pNew->pMethod = pLockingStyle;
239 @@ -4613,37 +4658,6 @@ int fillInUnixFile(
240 }
241
242 /*
243 -** Open a file descriptor to the directory containing file zFilename.
244 -** If successful, *pFd is set to the opened file descriptor and
245 -** SQLITE_OK is returned. If an error occurs, either SQLITE_NOMEM
246 -** or SQLITE_CANTOPEN is returned and *pFd is set to an undefined
247 -** value.
248 -**
249 -** If SQLITE_OK is returned, the caller is responsible for closing
250 -** the file descriptor *pFd using close().
251 -*/
252 -static int openDirectory(const char *zFilename, int *pFd){
253 - int ii;
254 - int fd = -1;
255 - char zDirname[MAX_PATHNAME+1];
256 -
257 - sqlite3_snprintf(MAX_PATHNAME, zDirname, "%s", zFilename);
258 - for(ii=(int)strlen(zDirname); ii>1 && zDirname[ii]!='/'; ii--);
259 - if( ii>0 ){
260 - zDirname[ii] = '\0';
261 - fd = robust_open(zDirname, O_RDONLY|O_BINARY, 0);
262 - if( fd>=0 ){
263 -#ifdef FD_CLOEXEC
264 - osFcntl(fd, F_SETFD, osFcntl(fd, F_GETFD, 0) | FD_CLOEXEC);
265 -#endif
266 - OSTRACE(("OPENDIR %-3d %s\n", fd, zDirname));
267 - }
268 - }
269 - *pFd = fd;
270 - return (fd>=0?SQLITE_OK:unixLogError(SQLITE_CANTOPEN_BKPT, "open", zDirname)) ;
271 -}
272 -
273 -/*
274 ** Return the name of a directory in which to put temporary files.
275 ** If no suitable temporary file directory can be found, return NULL.
276 */
277 @@ -4757,7 +4771,7 @@ static UnixUnusedFd *findReusableFd(const char *zPath, int flags){
278 **
279 ** Even if a subsequent open() call does succeed, the consequences of
280 ** not searching for a resusable file descriptor are not dire. */
281 - if( 0==stat(zPath, &sStat) ){
282 + if( 0==osStat(zPath, &sStat) ){
283 unixInodeInfo *pInode;
284
285 unixEnterMutex();
286 @@ -4827,7 +4841,7 @@ static int findCreateFileMode(
287 memcpy(zDb, zPath, nDb);
288 zDb[nDb] = '\0';
289
290 - if( 0==stat(zDb, &sStat) ){
291 + if( 0==osStat(zDb, &sStat) ){
292 *pMode = sStat.st_mode & 0777;
293 }else{
294 rc = SQLITE_IOERR_FSTAT;
295 @@ -4938,7 +4952,6 @@ static int unixOpen(
296 ){
297 unixFile *p = (unixFile *)pFile;
298 int fd = -1; /* File descriptor returned by open() */
299 - int dirfd = -1; /* Directory file descriptor */
300 int openFlags = 0; /* Flags to pass to open() */
301 int eType = flags&0xFFFFFF00; /* Type of file to open */
302 int noLock; /* True to omit locking primitives */
303 @@ -4957,7 +4970,7 @@ static int unixOpen(
304 ** a file-descriptor on the directory too. The first time unixSync()
305 ** is called the directory file descriptor will be fsync()ed and close()d.
306 */
307 - int isOpenDirectory = (isCreate && (
308 + int syncDir = (isCreate && (
309 eType==SQLITE_OPEN_MASTER_JOURNAL
310 || eType==SQLITE_OPEN_MAIN_JOURNAL
311 || eType==SQLITE_OPEN_WAL
312 @@ -5004,7 +5017,7 @@ static int unixOpen(
313 }
314 }else if( !zName ){
315 /* If zName is NULL, the upper layer is requesting a temp file. */
316 - assert(isDelete && !isOpenDirectory);
317 + assert(isDelete && !syncDir);
318 rc = unixGetTempname(MAX_PATHNAME+1, zTmpname);
319 if( rc!=SQLITE_OK ){
320 return rc;
321 @@ -5057,7 +5070,7 @@ static int unixOpen(
322 #if OS_VXWORKS
323 zPath = zName;
324 #else
325 - unlink(zName);
326 + osUnlink(zName);
327 #endif
328 }
329 #if SQLITE_ENABLE_LOCKING_STYLE
330 @@ -5066,19 +5079,6 @@ static int unixOpen(
331 }
332 #endif
333
334 - if( isOpenDirectory ){
335 - rc = openDirectory(zPath, &dirfd);
336 - if( rc!=SQLITE_OK ){
337 - /* It is safe to close fd at this point, because it is guaranteed not
338 - ** to be open on a database file. If it were open on a database file,
339 - ** it would not be safe to close as this would release any locks held
340 - ** on the file by this process. */
341 - assert( eType!=SQLITE_OPEN_MAIN_DB );
342 - robust_close(p, fd, __LINE__);
343 - goto open_finished;
344 - }
345 - }
346 -
347 #ifdef FD_CLOEXEC
348 osFcntl(fd, F_SETFD, osFcntl(fd, F_GETFD, 0) | FD_CLOEXEC);
349 #endif
350 @@ -5090,7 +5090,6 @@ static int unixOpen(
351 struct statfs fsInfo;
352 if( fstatfs(fd, &fsInfo) == -1 ){
353 ((unixFile*)pFile)->lastErrno = errno;
354 - if( dirfd>=0 ) robust_close(p, dirfd, __LINE__);
355 robust_close(p, fd, __LINE__);
356 return SQLITE_IOERR_ACCESS;
357 }
358 @@ -5122,9 +5121,6 @@ static int unixOpen(
359 ** not while other file descriptors opened by the same process on
360 ** the same file are working. */
361 p->lastErrno = errno;
362 - if( dirfd>=0 ){
363 - robust_close(p, dirfd, __LINE__);
364 - }
365 robust_close(p, fd, __LINE__);
366 rc = SQLITE_IOERR_ACCESS;
367 goto open_finished;
368 @@ -5132,7 +5128,7 @@ static int unixOpen(
369 useProxy = !(fsInfo.f_flags&MNT_LOCAL);
370 }
371 if( useProxy ){
372 - rc = fillInUnixFile(pVfs, fd, dirfd, pFile, zPath, noLock,
373 + rc = fillInUnixFile(pVfs, fd, syncDir, pFile, zPath, noLock,
374 isDelete, isReadonly);
375 if( rc==SQLITE_OK ){
376 rc = proxyTransformUnixFile((unixFile*)pFile, ":auto:");
377 @@ -5150,7 +5146,7 @@ static int unixOpen(
378 }
379 #endif
380
381 - rc = fillInUnixFile(pVfs, fd, dirfd, pFile, zPath, noLock,
382 + rc = fillInUnixFile(pVfs, fd, syncDir, pFile, zPath, noLock,
383 isDelete, isReadonly);
384 open_finished:
385 if( rc!=SQLITE_OK ){
386 @@ -5172,13 +5168,13 @@ static int unixDelete(
387 int rc = SQLITE_OK;
388 UNUSED_PARAMETER(NotUsed);
389 SimulateIOError(return SQLITE_IOERR_DELETE);
390 - if( unlink(zPath)==(-1) && errno!=ENOENT ){
391 + if( osUnlink(zPath)==(-1) && errno!=ENOENT ){
392 return unixLogError(SQLITE_IOERR_DELETE, "unlink", zPath);
393 }
394 #ifndef SQLITE_DISABLE_DIRSYNC
395 if( dirSync ){
396 int fd;
397 - rc = openDirectory(zPath, &fd);
398 + rc = osOpenDirectory(zPath, &fd);
399 if( rc==SQLITE_OK ){
400 #if OS_VXWORKS
401 if( fsync(fd)==-1 )
402 @@ -5189,6 +5185,8 @@ static int unixDelete(
403 rc = unixLogError(SQLITE_IOERR_DIR_FSYNC, "fsync", zPath);
404 }
405 robust_close(0, fd, __LINE__);
406 + }else if( rc==SQLITE_CANTOPEN ){
407 + rc = SQLITE_OK;
408 }
409 }
410 #endif
411 @@ -5231,7 +5229,7 @@ static int unixAccess(
412 *pResOut = (osAccess(zPath, amode)==0);
413 if( flags==SQLITE_ACCESS_EXISTS && *pResOut ){
414 struct stat buf;
415 - if( 0==stat(zPath, &buf) && buf.st_size==0 ){
416 + if( 0==osStat(zPath, &buf) && buf.st_size==0 ){
417 *pResOut = 0;
418 }
419 }
420 @@ -5750,7 +5748,6 @@ static int proxyCreateUnixFile(
421 int islockfile /* if non zero missing dirs will be created */
422 ) {
423 int fd = -1;
424 - int dirfd = -1;
425 unixFile *pNew;
426 int rc = SQLITE_OK;
427 int openFlags = O_RDWR | O_CREAT;
428 @@ -5815,7 +5812,7 @@ static int proxyCreateUnixFile(
429 pUnused->flags = openFlags;
430 pNew->pUnused = pUnused;
431
432 - rc = fillInUnixFile(&dummyVfs, fd, dirfd, (sqlite3_file*)pNew, path, 0, 0, 0) ;
433 + rc = fillInUnixFile(&dummyVfs, fd, 0, (sqlite3_file*)pNew, path, 0, 0, 0);
434 if( rc==SQLITE_OK ){
435 *ppFile = pNew;
436 return SQLITE_OK;
437 @@ -5929,7 +5926,7 @@ static int proxyBreakConchLock(unixFile *pFile, uuid_t myH ostID){
438 end_breaklock:
439 if( rc ){
440 if( fd>=0 ){
441 - unlink(tPath);
442 + osUnlink(tPath);
443 robust_close(pFile, fd, __LINE__);
444 }
445 fprintf(stderr, "failed to break stale lock on %s, %s\n", cPath, errmsg);
446 @@ -6752,7 +6749,7 @@ int sqlite3_os_init(void){
447
448 /* Double-check that the aSyscall[] array has been constructed
449 ** correctly. See ticket [bb3a86e890c8e96ab] */
450 - assert( ArraySize(aSyscall)==16 );
451 + assert( ArraySize(aSyscall)==18 );
452
453 /* Register all VFSes defined in the aVfs[] array */
454 for(i=0; i<(sizeof(aVfs)/sizeof(sqlite3_vfs)); i++){
455 diff --git a/third_party/sqlite/src/test/syscall.test b/third_party/sqlite/src/t est/syscall.test
456 index 4442612..201bd63 100644
457 --- a/third_party/sqlite/src/test/syscall.test
458 +++ b/third_party/sqlite/src/test/syscall.test
459 @@ -59,7 +59,7 @@ do_test 2.1.2 { test_syscall exists nosuchcall } 0
460 foreach s {
461 open close access getcwd stat fstat ftruncate
462 fcntl read pread write pwrite fchmod fallocate
463 - pread64 pwrite64
464 + pread64 pwrite64 unlink openDirectory
465 } {
466 if {[test_syscall exists $s]} {lappend syscall_list $s}
467 }
468 --
469 2.2.1
470
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698