diff --git a/patch/0008-Rekey-multi-process.patch b/patch/0008-Rekey-multi-process.patch new file mode 100644 index 0000000000000000000000000000000000000000..2a6c3425f33ea5fafac3fb2fed3d8de9ae282f95 --- /dev/null +++ b/patch/0008-Rekey-multi-process.patch @@ -0,0 +1,180 @@ +From fa5b9fefdd1d5b13ad1953690ed93f21f26be9ac Mon Sep 17 00:00:00 2001 +From: ryne3366 +Date: Fri, 6 Jun 2025 19:42:36 +0800 +Subject: [PATCH 1/2] rekey multi process + +--- + src/sqlite3.c | 93 +++++++++++++++++++++++++++++++++++++++++++++++++-- + 1 file changed, 90 insertions(+), 3 deletions(-) + +diff --git a/src/sqlite3.c b/src/sqlite3.c +index 6530284..b808dc6 100644 +--- a/src/sqlite3.c ++++ b/src/sqlite3.c +@@ -15692,6 +15692,7 @@ typedef int VList; + #define RESERVED_BYTE (PENDING_BYTE+1) + #define SHARED_FIRST (PENDING_BYTE+2) + #define SHARED_SIZE 510 ++#define SHARED_CODEC_BYTE (PENDING_BYTE+2097) + + /* + ** Wrapper around OS specific sqlite3_os_init() function. +@@ -38678,6 +38679,10 @@ struct unixFile { + #endif + }; + ++#ifdef SQLITE_HAS_CODEC ++static int CodecFileLock(Pager *pPager, short lockType); ++#endif ++ + /* This variable holds the process id (pid) from when the xRandomness() + ** method was called. If xOpen() is called from a different process id, + ** indicating that a fork() has occurred, the PRNG will be reset. +@@ -39623,6 +39628,9 @@ struct unixInodeInfo { + sqlite3_mutex *pLockMutex; /* Hold this mutex for... */ + int nShared; /* Number of SHARED locks held */ + int nLock; /* Number of outstanding file locks */ ++#if SQLITE_HAS_CODEC ++ void *codecPager; ++#endif + unsigned char eFileLock; /* One of SHARED_LOCK, RESERVED_LOCK etc. */ + unsigned char bProcessLock; /* An exclusive process lock is held */ + UnixUnusedFd *pUnused; /* Unused file descriptors to close */ +@@ -61693,6 +61701,9 @@ SQLITE_PRIVATE int sqlite3PagerClose(Pager *pPager, sqlite3 *db){ + PAGERTRACE(("CLOSE %d\n", PAGERID(pPager))); + IOTRACE(("CLOSE %p\n", pPager)) + sqlite3OsClose(pPager->jfd); ++#if SQLITE_OS_UNIX && defined(SQLITE_HAS_CODEC) ++ if( pPager->xCodec ) CodecFileLock(pPager, F_UNLCK); ++#endif + sqlite3OsClose(pPager->fd); + sqlite3PageFree(pTmp); + sqlite3PcacheClose(pPager->pPCache); +@@ -255484,6 +255495,54 @@ void sqlite3CodecDetach(void *ctx){ + return; + } + ++#if SQLITE_OS_UNIX ++static int CodecFileLock(Pager *pPager, short lockType) ++{ ++ sqlite3_file *fd = pPager->fd; ++ unixFile *pFile = (unixFile *)fd; ++ unixInodeInfo *pInode = pFile->pInode; ++ if (pInode == NULL) { ++ sqlite3_log(SQLITE_IOERR_RDLOCK, "Codec file lock %d go wrong", lockType); ++ return SQLITE_IOERR_RDLOCK; ++ } ++ sqlite3_mutex_enter(pInode->pLockMutex); ++ // last conntection release the lock ++ if (lockType == F_UNLCK && pInode->nRef > 1) { ++ sqlite3_mutex_leave(pInode->pLockMutex); ++ return SQLITE_OK; ++ } ++ if (lockType == F_WRLCK && pInode->nRef > 1) { ++ sqlite3_mutex_leave(pInode->pLockMutex); ++ sqlite3_log(SQLITE_BUSY, "Codec file lock wrlock busy ref %d", pInode->nRef); ++ return SQLITE_BUSY; ++ } ++ if (lockType == F_RDLCK && pInode->codecPager != 0 && pInode->codecPager != pPager) { ++ sqlite3_mutex_leave(pInode->pLockMutex); ++ sqlite3_log(SQLITE_BUSY, "Codec exists file lock wrlock"); ++ return SQLITE_BUSY; ++ } ++ struct flock lock; ++ lock.l_whence = SEEK_SET; ++ lock.l_start = SHARED_CODEC_BYTE; ++ lock.l_len = 1; ++ // F_RDLCK, F_WRLCK, F_UNLCK ++ lock.l_type = lockType; ++ int rc = osSetPosixAdvisoryLock(pFile->h, &lock, pFile); ++ if (rc < 0) { ++ int tErrno = errno; ++ rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_RDLOCK); ++ if (IS_LOCK_ERROR(rc)) { ++ storeLastErrno(pFile, tErrno); ++ } ++ sqlite3_log(rc, "Codec file lock %d: errno = %d", lockType, tErrno); ++ } else { ++ pInode->codecPager = (lockType == F_WRLCK ? pPager : 0); ++ } ++ sqlite3_mutex_leave(pInode->pLockMutex); ++ return rc; ++} ++#endif ++ + int sqlite3CodecAttach(sqlite3* db, int nDb, const void *pKey, int nKey){ + if(db == NULL){ + return SQLITE_ERROR; +@@ -255503,6 +255562,18 @@ int sqlite3CodecAttach(sqlite3* db, int nDb, const void *pKey, int nKey){ + return SQLITE_ERROR; + } + sqlite3_mutex_enter(db->mutex); ++ Pager *pPager = p->pBt->pPager; ++#if SQLITE_OS_UNIX ++ if (pPager->fd != NULL && isOpen(pPager->fd)) { ++ int ret = CodecFileLock(pPager, F_RDLCK); ++ if(ret != SQLITE_OK){ ++ sqlite3_free(ctx); ++ sqlite3_mutex_leave(db->mutex); ++ sqlite3_log(ret, "sqlite3CodecAttach: codec lock error"); ++ return ret; ++ } ++ } ++#endif + #ifdef SQLITE_CODEC_ATTACH_CHANGED + int rc = sqlite3CodecInitContext(ctx, p, pKey, nKey, nDb); + #else +@@ -255510,6 +255581,7 @@ int sqlite3CodecAttach(sqlite3* db, int nDb, const void *pKey, int nKey){ + #endif /* SQLITE_CODEC_ATTACH_CHANGED */ + if(rc != SQLITE_OK){ + sqlite3_free(ctx); ++ sqlite3_mutex_leave(db->mutex); + return rc; + } + sqlite3PagerSetCodec(sqlite3BtreePager(p), sqlite3Codec, NULL, sqlite3CodecDetach, (void *)ctx); +@@ -255518,7 +255590,7 @@ int sqlite3CodecAttach(sqlite3* db, int nDb, const void *pKey, int nKey){ + p->pBt->btsFlags &= ~BTS_PAGESIZE_FIXED; + sqlite3BtreeSetPageSize(p, ctx->readCtx->codecConst.cipherPageSize, ctx->readCtx->codecConst.reserveSize, 0); + sqlite3BtreeSecureDelete(p, 1); +- if(isOpen(p->pBt->pPager->fd)){ ++ if(isOpen(pPager->fd)){ + sqlite3BtreeSetAutoVacuum(p, SQLITE_DEFAULT_AUTOVACUUM); + } + +@@ -255589,7 +255661,20 @@ int sqlite3_rekey_v2(sqlite3 *db, const char *zDb, const void *pKey, int nKey){ + return rc; + } + sqlite3_mutex_enter(db->mutex); +- (void)sqlite3BtreeBeginTrans(p, 1, 0); ++ rc = sqlite3BtreeBeginTrans(p, 1, 0); ++ if(rc != SQLITE_OK){ ++ sqlite3_mutex_leave(db->mutex); ++ sqlite3_log(rc, "sqlite3 rekey: error when begin trans %s.", sqlite3PagerFilename(pPager, 1)); ++ return rc; ++ } ++#if SQLITE_OS_UNIX ++ if((rc = CodecFileLock(pPager, F_WRLCK)) != SQLITE_OK){ ++ (void)sqlite3BtreeRollback(p, SQLITE_ABORT_ROLLBACK, 0); ++ sqlite3_mutex_leave(db->mutex); ++ sqlite3_log(rc, "sqlite3_rekey_v2: error when lock %s.", sqlite3PagerFilename(pPager, 1)); ++ return rc; ++ } ++#endif + sqlite3PagerPagecount(pPager, &pageCount); + // support hmac algo changed by using rekey operation + int oldHmacAlgo = ctx->writeCtx->codecConst.hmacAlgo; +@@ -255624,8 +255709,10 @@ int sqlite3_rekey_v2(sqlite3 *db, const char *zDb, const void *pKey, int nKey){ + } + (void)sqlite3BtreeRollback(p, SQLITE_ABORT_ROLLBACK, 0); + } ++#if SQLITE_OS_UNIX ++ (void)CodecFileLock(pPager, F_RDLCK); ++#endif + sqlite3_mutex_leave(db->mutex); +- + return rc; + } + +-- +2.34.1 + diff --git a/patch/0008-Bugfix-on-current-version.patch b/patch/0009-Bugfix-on-current-version.patch similarity index 75% rename from patch/0008-Bugfix-on-current-version.patch rename to patch/0009-Bugfix-on-current-version.patch index e8a7131c3d06d46bb1faeabb33324d7935e1a9c6..8dfd5006c2712631e379e03cc847b8a0eb74dc53 100644 --- a/patch/0008-Bugfix-on-current-version.patch +++ b/patch/0009-Bugfix-on-current-version.patch @@ -1,17 +1,17 @@ -From c345d90710d07dc32a29cfbf917c1420acd2479e Mon Sep 17 00:00:00 2001 +From 62fb2b915f2f13108f76f2d1359d7863c6124b80 Mon Sep 17 00:00:00 2001 From: ryne3366 -Date: Thu, 29 May 2025 17:18:58 +0800 -Subject: [PATCH] Bugfix on current version +Date: Fri, 6 Jun 2025 19:48:39 +0800 +Subject: [PATCH 2/2] Bug fixes on current version --- - src/sqlite3.c | 219 ++++++++++++++++++++++++++++++++++++++++---------- - 1 file changed, 177 insertions(+), 42 deletions(-) + src/sqlite3.c | 241 ++++++++++++++++++++++++++++++++++++++++---------- + 1 file changed, 194 insertions(+), 47 deletions(-) diff --git a/src/sqlite3.c b/src/sqlite3.c -index 6530284..5fb5efb 100644 +index b808dc6..a86cbf1 100644 --- a/src/sqlite3.c +++ b/src/sqlite3.c -@@ -38781,8 +38781,8 @@ static void enableDbFileDelMonitor(int32_t fd) +@@ -38786,8 +38786,8 @@ static void enableDbFileDelMonitor(int32_t fd) } flags |= HMFS_MONITOR_FL; ret = ioctl(fd, HMFS_IOCTL_HW_SET_FLAGS, &flags); @@ -22,7 +22,7 @@ index 6530284..5fb5efb 100644 } } -@@ -57778,6 +57778,8 @@ static void MetaDwrCheckVacuum(BtShared *pBt); +@@ -57786,6 +57786,8 @@ static void MetaDwrCheckVacuum(BtShared *pBt); static int MetaDwrRecoverAndBeginTran(Btree *pBt, int wrflag, int *pSchemaVersion); static int MetaDwrOpenAndCheck(Btree *pBt); static void MetaDwrDisable(Btree *pBt); @@ -31,7 +31,7 @@ index 6530284..5fb5efb 100644 #define META_HEADER_CHANGED 1 #define META_SCHEMA_CHANGED 2 #define META_IN_RECOVERY 1 -@@ -59556,11 +59558,12 @@ static int pager_end_transaction(Pager *pPager, int hasSuper, int bCommit){ +@@ -59564,11 +59566,12 @@ static int pager_end_transaction(Pager *pPager, int hasSuper, int bCommit){ sqlite3PcacheTruncate(pPager->pPCache, pPager->dbSize); } #ifdef SQLITE_META_DWR @@ -49,7 +49,7 @@ index 6530284..5fb5efb 100644 } #endif if( pagerUseWal(pPager) ){ -@@ -74661,6 +74664,11 @@ static int lockBtree(BtShared *pBt){ +@@ -74672,6 +74675,11 @@ static int lockBtree(BtShared *pBt){ } if( nPage>nPageFile ){ if( sqlite3WritableSchema(pBt->db)==0 ){ @@ -61,7 +61,7 @@ index 6530284..5fb5efb 100644 rc = SQLITE_CORRUPT_BKPT; goto page1_init_failed; }else{ -@@ -121509,8 +121517,8 @@ static void attachFunc( +@@ -121520,8 +121528,8 @@ static void attachFunc( if( rc==SQLITE_OK ){ extern int sqlite3CodecAttach(sqlite3*, int, const void*, int); extern void sqlite3CodecGetKey(sqlite3*, int, void**, int*); @@ -72,7 +72,7 @@ index 6530284..5fb5efb 100644 int t = sqlite3_value_type(argv[2]); switch( t ){ case SQLITE_INTEGER: -@@ -121527,14 +121535,7 @@ static void attachFunc( +@@ -121538,14 +121546,7 @@ static void attachFunc( break; case SQLITE_NULL: @@ -88,7 +88,7 @@ index 6530284..5fb5efb 100644 break; } } -@@ -183694,10 +183695,12 @@ opendb_out: +@@ -183705,10 +183706,12 @@ opendb_out: db->eOpenState = SQLITE_STATE_SICK; } #ifdef SQLITE_ENABLE_DROPTABLE_CALLBACK @@ -105,7 +105,7 @@ index 6530284..5fb5efb 100644 #endif /* SQLITE_ENABLE_DROPTABLE_CALLBACK */ #ifdef SQLITE_ENABLE_BINLOG sqlite3BinlogReset(db); -@@ -204147,6 +204150,39 @@ static int fts3ExprTermOffsetInit(Fts3Expr *pExpr, int iPhrase, void *ctx){ +@@ -204158,6 +204161,39 @@ static int fts3ExprTermOffsetInit(Fts3Expr *pExpr, int iPhrase, void *ctx){ return rc; } @@ -145,7 +145,7 @@ index 6530284..5fb5efb 100644 /* ** Implementation of offsets() function. */ -@@ -204183,6 +204219,12 @@ SQLITE_PRIVATE void sqlite3Fts3Offsets( +@@ -204194,6 +204230,12 @@ SQLITE_PRIVATE void sqlite3Fts3Offsets( sCtx.iDocid = pCsr->iPrevId; sCtx.pCsr = pCsr; @@ -158,7 +158,7 @@ index 6530284..5fb5efb 100644 /* Loop through the table columns, appending offset information to ** string-buffer res for each column. */ -@@ -254369,7 +254411,20 @@ SQLITE_API int sqlite3_stmt_init( +@@ -254380,7 +254422,20 @@ SQLITE_API int sqlite3_stmt_init( /* Return the source-id for this library */ SQLITE_API const char *sqlite3_sourceid(void){ return SQLITE_SOURCE_ID; } /************************** End of sqlite3.c ******************************/ @@ -180,15 +180,15 @@ index 6530284..5fb5efb 100644 #ifdef SQLITE_HAS_CODEC /************** Begin file hw_codec_openssl.h *******************************/ #ifndef EXPOSE_INTERNAL_FUNC -@@ -255503,6 +255558,7 @@ int sqlite3CodecAttach(sqlite3* db, int nDb, const void *pKey, int nKey){ - return SQLITE_ERROR; +@@ -255574,6 +255629,7 @@ int sqlite3CodecAttach(sqlite3* db, int nDb, const void *pKey, int nKey){ + } } - sqlite3_mutex_enter(db->mutex); + #endif + p->pBt->btsFlags &= ~BTS_PAGESIZE_FIXED; #ifdef SQLITE_CODEC_ATTACH_CHANGED int rc = sqlite3CodecInitContext(ctx, p, pKey, nKey, nDb); #else -@@ -256017,7 +256073,12 @@ typedef struct MetaDwrHdr { +@@ -256104,7 +256160,12 @@ typedef struct MetaDwrHdr { u32 pageSz; u32 pageCnt; u64 dbFileInode; @@ -202,7 +202,7 @@ index 6530284..5fb5efb 100644 u32 checkSum; u8 *zones; Pgno *pages; -@@ -256372,6 +256433,87 @@ static inline u64 CaculateMetaDwrWriteOffset(int pageSz, u32 idx, u8 zone) { +@@ -256459,6 +256520,87 @@ static inline u64 CaculateMetaDwrWriteOffset(int pageSz, u32 idx, u8 zone) { return META_DWR_HEADER_PAGE_SIZE + pageSz * (idx * 2 + zone); } @@ -290,7 +290,7 @@ index 6530284..5fb5efb 100644 static void MetaDwrUpdateHeaderDbInfo(BtShared *pBt) { MetaDwrHdr *hdr = pBt->pPager->metaHdr; // 28 offset: dbSize, freelist pageNo, freelist pages count, schema cookie -@@ -256592,11 +256734,12 @@ static int MetaDwrOpenFile(Pager *pPager, u8 openCreate) { +@@ -256679,11 +256821,12 @@ static int MetaDwrOpenFile(Pager *pPager, u8 openCreate) { if (pPager->metaMapPage == NULL) { sqlite3_int64 sz = META_DWR_HEADER_PAGE_SIZE; sqlite3OsFileControlHint(metaFd, SQLITE_FCNTL_CHUNK_SIZE, &sz); @@ -308,7 +308,52 @@ index 6530284..5fb5efb 100644 } } #endif -@@ -257058,19 +257201,6 @@ static void MetaDwrDisable(Btree *pBt) +@@ -257057,15 +257200,23 @@ CHK_RESTORE_OUT: + return rc; + } + +-static inline u8 IsConnectionValidForCheck(Pager *pPager) ++static inline u8 IsOnlyOneConnection(Pager *pPager) + { + #if SQLITE_OS_UNIX + unixFile *fd = (unixFile *)pPager->fd; +- // unix and only one connection exist + if (fd == NULL || fd->pInode == NULL || pPager->pVfs == NULL || +- sqlite3_stricmp(pPager->pVfs->zName, "unix") != 0 || fd->pInode->nRef != 1) { ++ sqlite3_stricmp(pPager->pVfs->zName, "unix") != 0) { ++ sqlite3_log(SQLITE_WARNING_DUMP, "Check connection go wrong"); + return 0; + } ++ unixInodeInfo *pInode = fd->pInode; ++ sqlite3_mutex_enter(pInode->pLockMutex); ++ // unix and only one connection exist ++ if (pInode->nRef != 1) { ++ sqlite3_mutex_leave(pInode->pLockMutex); ++ return 0; ++ } ++ sqlite3_mutex_leave(pInode->pLockMutex); + return 1; + #else + return 0; +@@ -257075,7 +257226,7 @@ static inline u8 IsConnectionValidForCheck(Pager *pPager) + static int MetaDwrOpenAndCheck(Btree *pBt) + { + Pager *pPager = pBt->pBt->pPager; +- if (pPager->memDb || pPager->readOnly || !IsConnectionValidForCheck(pPager)) { ++ if (pPager->memDb || pPager->readOnly || !IsOnlyOneConnection(pPager)) { + return SQLITE_OK; + } + #ifdef SQLITE_HAS_CODEC +@@ -257120,7 +257271,7 @@ DWR_OPEN_OUT: + static void MetaDwrDisable(Btree *pBt) + { + Pager *pPager = pBt->pBt->pPager; +- if (pPager->metaFd == NULL || pPager->memDb || pPager->readOnly || !IsConnectionValidForCheck(pPager)) { ++ if (pPager->metaFd == NULL || pPager->memDb || pPager->readOnly || !IsOnlyOneConnection(pPager)) { + return; + } + #ifdef SQLITE_HAS_CODEC +@@ -257145,19 +257296,6 @@ static void MetaDwrDisable(Btree *pBt) } #endif #if SQLITE_OS_UNIX @@ -328,7 +373,7 @@ index 6530284..5fb5efb 100644 static void ResetLockStatus(void) { (void)memset(&g_lockStatus, 0, sizeof(g_lockStatus)); -@@ -257174,8 +257304,13 @@ static inline const char *FlockToName(int l_type) +@@ -257261,8 +257399,13 @@ static inline const char *FlockToName(int l_type) static int DumpProcessLocks(int fd, struct flock *lock, const char *lockName, char *dumpBuf, int bufLen) { @@ -343,6 +388,18 @@ index 6530284..5fb5efb 100644 sqlite3_log(SQLITE_ERROR, "[SQLite]Get wal file lock ofs %u failed, errno: %d", lock->l_start, errno); return 0; } +@@ -258317,7 +258460,11 @@ struct sqlite3_api_routines_hw { + int (*rekey_v2)(sqlite3*,const char*,const void*,int); + int (*is_support_binlog)(void); + int (*replay_binlog)(sqlite3*, sqlite3*); ++#ifdef SQLITE_ENABLE_BINLOG + int (*clean_binlog)(sqlite3*, BinlogFileCleanModeE); ++#else ++ void *dymmyFunc; ++#endif + }; + + typedef struct sqlite3_api_routines_hw sqlite3_api_routines_hw; -- -2.28.0.windows.1 +2.34.1