]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
New symbolic representation of posix advisory locking information
authordrh <>
Sat, 25 Oct 2025 12:53:03 +0000 (12:53 +0000)
committerdrh <>
Sat, 25 Oct 2025 12:53:03 +0000 (12:53 +0000)
FossilOrigin-Name: b7d991ae04da1d6731b67fbdca65df996ec1c14a9530880fb7dbeeaef2575d14

manifest
manifest.uuid
src/os_unix.c

index 7f370f51348661ccc6d2040a4b01ab00c27a4cdf..9ff5674e5ff50b760fc8621788800b9871832a7b 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Merge\strunk\senhancements\sinto\sthe\sfile-info\sbranch.
-D 2025-10-25T11:47:04.114
+C New\ssymbolic\srepresentation\sof\sposix\sadvisory\slocking\sinformation
+D 2025-10-25T12:53:03.679
 F .fossil-settings/binary-glob 61195414528fb3ea9693577e1980230d78a1f8b0a54c78cf1b9b24d0a409ed6a x
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
@@ -720,7 +720,7 @@ F src/os.h 1ff5ae51d339d0e30d8a9d814f4b8f8e448169304d83a7ed9db66a65732f3e63
 F src/os_common.h 6c0eb8dd40ef3e12fe585a13e709710267a258e2c8dd1c40b1948a1d14582e06
 F src/os_kv.c fb7ba8d6204197357f1eb7e1c7450d09c10043bf7e99aba602f4aa46b8fb11a3
 F src/os_setup.h 8efc64eda6a6c2f221387eefc2e7e45fd5a3d5c8337a7a83519ba4fbd2957ae2
-F src/os_unix.c ec6d9ea99794f93b5f4a2ca5769f99c71e967741b574ff9debdea5825b5d5bd5
+F src/os_unix.c 2fc3126f296960d16fe2a52ef3b77cdb5637e2ac036c28c586c90766c9a7123b
 F src/os_win.c 5b14841f9c3ab76841c06a4eca20ba3e7747f44253eba9dfd3d918797e753d49
 F src/os_win.h 4c247cdb6d407c75186c94a1e84d5a22cbae4adcec93fcae8d2bc1f956fd1f19
 F src/pager.c 113f9149092ccff6cf90e97c2611200e5a237f13d26c394bc9fd933377852764
@@ -2171,8 +2171,8 @@ F tool/version-info.c 33d0390ef484b3b1cb685d59362be891ea162123cea181cb8e6d2cf6dd
 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7
 F tool/warnings.sh 1ad0169b022b280bcaaf94a7fa231591be96b514230ab5c98fbf15cd7df842dd
 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
-P f2809dd3b266c0a6a6eb4ed62812a907493fb4006d26f8905df7ff2b1ca01a5e ed01ed337c04cce4cdbb6e80628b6f716d537e072b80067bd2bd6c5d18a1454f
-R 7dd67122ca255adb0444f8e501e60504
+P 73e1e081e9f7fc0ece98222669d13abde16197f0befc3343246a9e7da7856f02
+R d02e1e5caa702fab091cddd2d527ec9a
 U drh
-Z 4ce899c38987e188b278f4b05ec7c492
+Z fc91506e75939b3bd259b47f9c0d4832
 # Remove this line to create a well-formed Fossil manifest.
index 7c98774d7ab8640712abd29336462985178325f0..33045881ab6ce81b57e87e40893c505eab613284 100644 (file)
@@ -1 +1 @@
-73e1e081e9f7fc0ece98222669d13abde16197f0befc3343246a9e7da7856f02
+b7d991ae04da1d6731b67fbdca65df996ec1c14a9530880fb7dbeeaef2575d14
index ed1c938a4169a7cfbb60a49ab47aa6a683addff9..a1423559544b9d6bcc22b78b2b1bde4f95331b6e 100644 (file)
@@ -596,46 +596,74 @@ static struct unix_syscall {
 }; /* End of the overrideable system calls */
 
 
-#if __linux__  && \
-    (defined(SQLITE_DEBUG) \
-      || defined(SQLITE_ENABLE_FILE_INFO) \
-      || defined(SQLITE_ENABLE_PAL_ASSERT))
-                            /* ^^^--- Mnemonic: Posix Advisory Lock */
+#if defined(SQLITE_DEBUG) || defined(SQLITE_ENABLE_FILE_INFO)
 /*
-** Examine locking information from the /proc/PID/fdinfo/FD pseudo-file.
+** Extract Posix Advisory Locking information about file description fd
+** from the /proc/PID/fdinfo/FD pseudo-file.  Fill the string buffer a[16]
+** with characters to indicate which SQLite-relevant locks are held.
+** a[16] will be a 15-character zero-terminated string with the following
+** schema:
+**
+**     AAA/B.DDD.DDDDD
+**
+** Each of character A-D will be "w" or "r" or "-" to indicate either a
+** write-lock, a read-lock, or no-lock, respectively.  The "." and "/"
+** characters are delimiters intended to make the string more easily
+** readable by humans.  Here are the meaning of the specific letters:
+**
+**     AAA   ->    The main database locks.  PENDING_BYTE, RESERVED_BYTE,
+**                 and SHARED_FIRST, respectively.
 **
-** If pStr is not NULL, append text that describes the locks to pStr.
+**     B     ->    The deadman switch lock.  Offset 128 of the -shm file.
 **
-** if iAssert is not 0, then verify that the there exists an posix
-** advisory lock (PAL) on byte iAssert of the file that fd is pointing
-** to.
+**     CCC   ->    WAL locks:  WRITE, CKPT, RECOVER
 **
-** This routine no-ops if /proc/PID/fdinfo/FD cannot be opened.
+**     DDDDD ->    WAL read-locks 0 through 5
 **
-** This routine is intended for diagnostic purposes only and is not a part
-** of ordinary builds.
+** Note that elements before the "/" apply to the main database file and
+** elements after the "/" apply to the -shm file in WAL mode.
+**
+** Here is another way of thinking about the meaning of the result string:
+**
+**           AAA/B.CCC.DDDDD
+**           ||| | ||| \___/
+**  PENDING--'|| | |||   `----- READ 0-5
+**  RESERVED--'| | ||`---- RECOVER
+**  SHARED ----' | |`----- CKPT
+**     DMS ------' `------ WRITE
+**
+** Return SQLITE_OK on success and SQLITE_ERROR_UNABLE if the /proc
+** pseudo-filesystem is unavailable.
 */
-static void unixProcFSLocks(
-  int fd,                 /* The file descriptor to analyze */
-  sqlite3_str *pStr,      /* Write a text description of PALs here */
-  sqlite3_uint64 iAssert  /* Assert that this lock is held */
+static int unixPosixAdvisoryLocks(
+  int fd,        /* The file descriptor to analyze */
+  char a[16]     /* Write a text description of PALs here */
 ){
   int in;
   ssize_t n;
   char *p, *pNext, *x;
-  int nLock = 0;
   char z[2000];
 
+        /*             1     */
+        /*   012 4 678 01234 */
+  memcpy(a, "---/-.---.-----", 16);
   sqlite3_snprintf(sizeof(z), z, "/proc/%d/fdinfo/%d", getpid(), fd);
   in = open(z, O_RDONLY);
   if( in<0 ){
-    if( pStr ) sqlite3_str_appendall(pStr,"(not-available)");
-    return;
+    return SQLITE_ERROR_UNABLE;
   }
   n = read(in, z, sizeof(z)-1);
   close(in);
-  if( n<=0 ) return;
+  if( n<=0 ) return SQLITE_ERROR_UNABLE;
   z[n] = 0;
+
+  /* We are looking for lines that begin with "lock:\t".  Examples:
+  **
+  ** lock: 1: POSIX  ADVISORY  READ 494716 08:02:5277597 1073741826 1073742335
+  ** lock: 1: POSIX  ADVISORY  WRITE 494716 08:02:5282282 120 120
+  ** lock: 2: POSIX  ADVISORY  READ 494716 08:02:5282282 123 123
+  ** lock: 3: POSIX  ADVISORY  READ 494716 08:02:5282282 128 128
+  */
   pNext = strstr(z, "lock:\t");
   while( pNext ){
     char cType = 0;
@@ -643,60 +671,43 @@ static void unixProcFSLocks(
     p = pNext+6;
     pNext = strstr(p, "lock:\t");
     if( pNext ) pNext[-1] = 0;
-    if( strstr(p, " READ ")!=0 ){
-      cType = 'R';
-    }else if( strstr(p, " WRITE ")!=0 ){
-      cType = 'W';
+    if( (x = strstr(p, " READ "))!=0 ){
+      cType = 'r';
+      x += 6;
+    }else if( (x = strstr(p, " WRITE "))!=0 ){
+      cType = 'w';
+      x += 7;
+    }else{
+      continue;
     }
-    if( cType==0 ) continue;
-    x = strrchr(p, ' ');
+    x = strrchr(x, ' ');
     if( x==0 ) continue;
     iLast = strtoll(x+1, 0, 10);
     *x = 0;
     x = strrchr(p, ' ');
     if( x==0 ) continue;
     iFirst = strtoll(x+1, 0, 10);
-    if( pStr ){
-      const int shmBase = (22+SQLITE_SHM_NLOCK)*4;
-      if( (nLock++)>0 ) sqlite3_str_append(pStr," ",1);
-      sqlite3_str_appendf(pStr, "%c ", cType);
-      if( iFirst>=PENDING_BYTE ){
-        /*  "P+" stands for PENDING_BYTE+ */
-        sqlite3_str_appendf(pStr, "P+%lld", iFirst - PENDING_BYTE);
-      }else if( iFirst>=shmBase ){
-        /*  "B+" stands for UNIX_SHM_BASE+ */
-        sqlite3_str_appendf(pStr, "B+%lld", iFirst - shmBase);
-      }else{
-        sqlite3_str_appendf(pStr, "%lld", iFirst);
-      }
-      if( iLast>iFirst ){
-        sqlite3_str_appendf(pStr,"(%lld)", iLast-iFirst+1);
-      }
+    if( iLast>=PENDING_BYTE ){
+      if( iFirst<=PENDING_BYTE && iLast>=PENDING_BYTE )     a[0] = cType;
+      if( iFirst<=PENDING_BYTE+1 && iLast>=PENDING_BYTE+1 ) a[1] = cType;
+      if( iFirst<=PENDING_BYTE+2 && iLast>=PENDING_BYTE+510 ) a[2] = cType;
+    }else if( iLast<=128 ){
+      if( iFirst<=128 && iLast>=128 ) a[4] = cType;
+      if( iFirst<=120 && iLast>=120 ) a[6] = cType;
+      if( iFirst<=121 && iLast>=121 ) a[7] = cType;
+      if( iFirst<=122 && iLast>=122 ) a[8] = cType;
+      if( iFirst<=123 && iLast>=123 ) a[10] = cType;
+      if( iFirst<=124 && iLast>=124 ) a[11] = cType;
+      if( iFirst<=125 && iLast>=125 ) a[12] = cType;
+      if( iFirst<=126 && iLast>=126 ) a[13] = cType;
+      if( iFirst<=127 && iLast>=127 ) a[14] = cType;
     }
-    if( iAssert>=iFirst && iAssert<=iLast ) iAssert = 0;
-  }
-#if defined(SQLITE_ENABLE_PAL_ASSERT) || defined(SQLITE_DEBUG)
-  if( iAssert ){
-    sqlite3_snprintf(sizeof(z), z,
-         "a Posix-advisory lock is missing from byte %lld of fd %d\n",
-         iAssert, fd);
-    write(2, z, strlen(z));
-    abort();
   }
-#else
-  (void)iAssert;
-#endif
+  return SQLITE_OK;
 }
 #else
-#  define unixProcFSLocks(A,B,C)  /* no-op */
-#endif /* __linux__ && (SQLITE_DEBUG || SQLITE_ENABLE_<various>) */
-
-/*
-** If compiled with -DSQLITE_ENABLE_PAL_ASSERT, then the ASSERT_PAL_HELD(X,Y)
-** macro will print an error on file descriptor 2 and abort if there is
-** no PAL on byte Y of file-descriptor x.
-*/
-#define ASSERT_PAL_HELD(fd,loc) unixProcFSLocks(fd,0,loc)
+#  define unixPosixAdvisoryLocks(A,B) SQLITE_ERROR_UNABLE
+#endif /* SQLITE_DEBUG || SQLITE_ENABLE_FILE_INFO */
 
 /*
 ** On some systems, calls to fchown() will trigger a message in a security
@@ -2221,7 +2232,6 @@ static int posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){
       lock.l_type = F_UNLCK;
       lock.l_whence = SEEK_SET;
       lock.l_start = lock.l_len = 0L;
-      /* ASSERT_PAL_HELD(pFile->h, PENDING_BYTE+2); */
       if( unixFileLock(pFile, &lock)==0 ){
         pInode->eFileLock = NO_LOCK;
       }else{
@@ -4255,6 +4265,7 @@ static int unixFileControl(sqlite3_file *id, int op, void *pArg){
 #if defined(SQLITE_DEBUG) || defined(SQLITE_ENABLE_FILE_INFO)
     case SQLITE_FCNTL_GET_INFO: {
       sqlite3_str *pStr = (sqlite3_str*)pArg;
+      char aLck[16];
       sqlite3_str_appendf(pStr, "{\"h\":%d", pFile->h);
       sqlite3_str_appendf(pStr, ",\"vfs\":\"%s\"", pFile->pVfs->zName);
       if( pFile->eFileLock ){
@@ -4263,11 +4274,9 @@ static int unixFileControl(sqlite3_file *id, int op, void *pArg){
         sqlite3_str_appendf(pStr, ",\"eFileLock\":\"%s\"", 
                                   azLock[pFile->eFileLock-1]);
       }
-#if __linux__
-      sqlite3_str_appendall(pStr, ",\"locks\":\"");
-      unixProcFSLocks(pFile->h, pStr, 0);
-      sqlite3_str_append(pStr, "\"", 1);
-#endif /* __linux__ */
+      if( unixPosixAdvisoryLocks(pFile->h, aLck)==SQLITE_OK ){
+        sqlite3_str_appendf(pStr, ",\"pal\":\"%s\"", aLck);
+      }
       if( pFile->pShm ){
         sqlite3_str_appendall(pStr, ",\"shm\":");
         unixDescribeShm(pStr, pFile->pShm);
@@ -4554,14 +4563,13 @@ struct unixShm {
 */
 static void unixDescribeShm(sqlite3_str *pStr, unixShm *pShm){
   unixShmNode *pNode = pShm->pShmNode;
+  char aLck[16];
   sqlite3_str_appendf(pStr, "{\"sharedMask\":%d", pShm->sharedMask);
   sqlite3_str_appendf(pStr, ",\"exclMask\":%d", pShm->exclMask);
   sqlite3_str_appendf(pStr, ",\"hShm\":%d", pNode->hShm);
-#if __linux__
-  sqlite3_str_appendall(pStr, ",\"locks\":\"");
-  unixProcFSLocks(pNode->hShm, pStr, 0);
-  sqlite3_str_append(pStr, "\"", 1);
-#endif /* __linux__ */
+  if( unixPosixAdvisoryLocks(pNode->hShm, aLck)==SQLITE_OK ){
+    sqlite3_str_appendf(pStr, ",\"pal\":\"%s\"", aLck);
+  }
   sqlite3_str_append(pStr, "}", 1);
 }
 #endif /* SQLITE_DEBUG || SQLITE_ENABLE_FILE_INFO */
@@ -4625,9 +4633,6 @@ static int unixShmSystemLock(
        || (ofst>=UNIX_SHM_BASE && ofst+n<=(UNIX_SHM_BASE+SQLITE_SHM_NLOCK))
   );
   if( ofst==UNIX_SHM_DMS ){
-    if( lockType==F_UNLCK && pShmNode->hShm>=0 ){
-      ASSERT_PAL_HELD(pShmNode->hShm, ofst);
-    }
     assert( pShmNode->nRef>0 || unixMutexHeld() );
     assert( pShmNode->nRef==0 || sqlite3_mutex_held(pShmNode->pShmMutex) );
   }else{