Changeset 836


Ignore:
Timestamp:
Nov 25, 2013, 6:40:10 PM (12 years ago)
Author:
Silvan Scherrer
Message:

Samba 3.5: use fcntl and friends for locking

Location:
branches/samba-3.5.x
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • branches/samba-3.5.x/lib/tdb/common/io.c

    r599 r836  
    9393        // YD we must upgrade read locks to write locks (exclusive), otherwise
    9494        // the owner (us) is not allowed to write to the file (different from unix)
    95         TDB_LOG((tdb, TDB_DEBUG_TRACE,"unlocking at %d len=%d before writing.\n", off, len));
    96         tdb_brlock( tdb, off, F_UNLCK, F_SETLK, 0, 1);
    9795        // if a wider previous lock is in effect, we cannot write lock our segment
    9896        // (e.g. a lock_upgrade locks all the file), so we hope the previous lock
    9997        // is a write lock: do not wait for lock.
    100         tdb_brlock( tdb, off, F_WRLCK, F_SETLK, 0, len);
     98        int upgradeLockRC = tdb_brlock( tdb, off, F_WRLCK, F_SETLK, 0, len);
     99        TDB_LOG((tdb, TDB_DEBUG_TRACE,"upgrading lock at %d len=%d "
     100                "before writing %s (rc=%d).\n", off, len,
     101                 upgradeLockRC ? "was successfull":"failed", upgradeLockRC));
    101102#endif
    102103
     
    127128                                 len, off));
    128129
    129 #ifdef __OS2__ // remove our lock
    130                         tdb_brlock( tdb, off, F_UNLCK, F_SETLK, 0, len);
     130#ifdef __OS2__ // remove our lock, if upgrade succeded
     131                        if (upgradeLockRC == 0)
     132                                tdb_brlock( tdb, off, F_UNLCK, F_SETLK, 0, len);
    131133#endif
    132134                        return -1;
     
    134136        }
    135137
    136 #ifdef __OS2__ // remove our lock
    137         tdb_brlock( tdb, off, F_UNLCK, F_SETLK, 0, len);
     138#ifdef __OS2__ // remove our lock, if upgrade succeded
     139                        if (upgradeLockRC == 0)
     140                                tdb_brlock( tdb, off, F_UNLCK, F_SETLK, 0, len);
    138141#endif
    139142
  • branches/samba-3.5.x/lib/tdb/common/lock.c

    r829 r836  
    3030#define TDB_MARK_LOCK 0x80000000
    3131
    32 #ifdef __OS2__
    33 
    34 static char* lock_type( int lck)
    35 {
    36         static char buffer[16];
    37         switch(lck) {
    38         case F_GETLK: return "F_GETLK";
    39         case F_SETLK: return "F_SETLK";
    40         case F_SETLKW: return "F_SETLKW";
    41         default:
    42                 sprintf( buffer, "unknown %d", lck);
    43         }
    44         return buffer;
    45 }
    46 
    47 static char* read_type( int rw)
    48 {
    49         static char buffer[16];
    50         switch(rw) {
    51         case F_RDLCK: return "F_RDLCK";
    52         case F_UNLCK: return "F_UNLCK";
    53         case F_WRLCK: return "F_WRLCK";
    54         default:
    55                 sprintf( buffer, "unknown %d", rw);
    56         }
    57         return buffer;
    58 }
    59 
    60 static int _mutex_brlock(struct tdb_context *tdb, tdb_off_t offset,
    61                int rw_type, int lck_type, int probe, size_t len)
    62 {
    63         HMTX    hSem;
    64         ULONG   ulTimeout;
    65         APIRET  rc;
    66        
    67         switch( offset) {
    68         case GLOBAL_LOCK:
    69                 hSem = tdb->hGlobalLock;
    70                 break;
    71         case ACTIVE_LOCK:
    72                 hSem = tdb->hActiveLock;
    73                 break;
    74         case TRANSACTION_LOCK:
    75                 hSem = tdb->hTransactionLock;
    76                 break;
    77         default:
    78                 TDB_LOG((tdb, TDB_DEBUG_FATAL, "_mutex_brlock unknown offset %d\n", offset));
    79                 exit(1);
    80         }
    81         if (hSem == 0) {
    82                 TDB_LOG((tdb, TDB_DEBUG_FATAL, "_mutex_brlock unknown sem handle offset %d\n", offset));
    83                 exit(1);
    84         }
    85 
    86         TDB_LOG((tdb, TDB_DEBUG_TRACE,"_mutex_brlock handle %d, offset %d\n", hSem, offset));
    87 
    88         if (lck_type == F_SETLKW)
    89                 ulTimeout = SEM_INDEFINITE_WAIT;
    90         else
    91                 ulTimeout = SEM_IMMEDIATE_RETURN;
    92 
    93         switch (rw_type) {
    94         case F_UNLCK:
    95                 rc = DosReleaseMutexSem( hSem);
    96                 break;
    97         case F_RDLCK:
    98         case F_WRLCK:
    99                 rc = DosRequestMutexSem( hSem, ulTimeout);
    100                 break;
    101         default:
    102                 TDB_LOG((tdb, TDB_DEBUG_FATAL, "_mutex_brlock unknown rw_type request %d\n", rw_type));
    103                 exit(1);
    104                 break;
    105         }
    106 
    107         if (rc == NO_ERROR
    108                 || rc == ERROR_SEM_OWNER_DIED
    109                 || rc == ERROR_NOT_OWNER)
    110                 return 0;
    111 
    112         errno = EINVAL;
    113         TDB_LOG(( tdb, TDB_DEBUG_ERROR, "_mutex_brlock pid %X, failed (fd=%d) at offset %d rw_type=%d lck_type=%d len=%d, rc=%d\n",
    114                  getpid(), tdb->fd, offset, rw_type, lck_type, (int)len, rc));
    115         tdb->ecode = TDB_ERR_LOCK;
    116         return -1;
    117 }
    118 #endif
    11932
    12033void tdb_setalarm_sigptr(struct tdb_context *tdb, volatile sig_atomic_t *ptr)
     
    13548{
    13649
    137 #ifdef __OS2__
    138         APIRET      rc;
    139         ULONG       fAccess = 0;
    140         FILELOCK    lockArea = {0}, unlockArea = {0};
    141 
    142         TDB_LOG((tdb, TDB_DEBUG_TRACE, "tdb_brlock in pid %X, fd %d, lck_type %s, rw_type %s, offset %d, len %d\n",
    143                 getpid(), tdb->fd, lock_type(lck_type), read_type(rw_type), offset, len));
    144 
    145         if (tdb->flags & TDB_NOLOCK) {
    146                 return 0;
    147         }
    148 
    149         if ((rw_type == F_WRLCK) && (tdb->read_only || tdb->traverse_read)) {
    150                 tdb->ecode = TDB_ERR_RDONLY;
    151                 return -1;
    152         }
    153        
    154         switch( offset) {
    155         case GLOBAL_LOCK:
    156         case ACTIVE_LOCK:
    157         case TRANSACTION_LOCK:
    158                 return _mutex_brlock( tdb, offset, rw_type,  lck_type,  probe, len);
    159         }
    160 
    161         /* flags and order */
    162         switch (rw_type)
    163         {
    164                 case F_UNLCK:
    165                         unlockArea.lOffset = offset;
    166                         unlockArea.lRange  = len ? len : LONG_MAX;
    167                         break;
    168                 case F_RDLCK:
    169                         lockArea.lOffset = offset;
    170                         lockArea.lRange  = len ? len : LONG_MAX;
    171                         fAccess = 1; /* read-only */
    172                 case F_WRLCK:
    173                         lockArea.lOffset = offset;
    174                         lockArea.lRange  = len ? len : LONG_MAX;
    175                         break;
    176                 default:
    177                         break;
    178         }
    179                
    180         rc = DosSetFileLocks(tdb->fd, &unlockArea, &lockArea, SEM_IMMEDIATE_RETURN, fAccess);
    181 
    182         if (rc != NO_ERROR && lck_type == F_SETLKW) {
    183                 int     count = 20;
    184                 do {
    185                         rc = DosSetFileLocks(tdb->fd, &unlockArea, &lockArea, 100, fAccess);
    186                         count--;
    187                 } while( count>0 && rc !=NO_ERROR);
    188 
    189         }
    190 
    191         TDB_LOG(( tdb, TDB_DEBUG_TRACE, "tdb_brlock out pid %d, fd %d, lck_type %s, rw_type %s, offset %d, len %d, rc=%d\n",
    192                 getpid(), tdb->fd, lock_type(lck_type), read_type(rw_type), offset, len, rc));
    193 
    194         if (rc != NO_ERROR) {
    195                 errno  = EINVAL;
    196                 /* Generic lock error. errno set by fcntl.
    197                  * EAGAIN is an expected return from non-blocking
    198                  * locks. */
    199                 if (!probe && lck_type != F_SETLK) {
    200                         /* Ensure error code is set for log fun to examine. */
    201                         tdb->ecode = TDB_ERR_LOCK;
    202                         TDB_LOG((tdb, TDB_DEBUG_TRACE,"tdb_brlock failed (fd=%d) at offset %d rw_type=%d lck_type=%d len=%d\n",
    203                                  tdb->fd, offset, rw_type, lck_type, (int)len));
    204                 }
    205 
    206                 TDB_LOG(( tdb, TDB_DEBUG_TRACE, "tdb_brlock pid %X, failed (fd=%d) at offset %d rw_type=%d lck_type=%d len=%d\n",
    207                          getpid(), tdb->fd, offset, rw_type, lck_type, (int)len));
    208                 tdb->ecode = TDB_ERR_LOCK;
    209                 return -1;
    210         }
    211 #else
    212 
    21350        struct flock fl;
    21451        int ret;
     
    22663        fl.l_whence = SEEK_SET;
    22764        fl.l_start = offset;
     65#ifdef __OS2__
     66        fl.l_len = len ? len:LONG_MAX;
     67#else
    22868        fl.l_len = len;
     69#endif
    22970        fl.l_pid = 0;
    23071
     
    25192                return -1;
    25293        }
    253 #endif
    25494        return 0;
    25595
     
    268108        while (count--) {
    269109                struct timeval tv;
    270 
    271 #ifdef __OS2__
    272                 // YD we cannot upgrade without an unlock first...
    273                 tdb_brlock(tdb, offset, F_UNLCK, F_SETLKW, 1, len);
    274 #endif
    275110
    276111                if (tdb_brlock(tdb, offset, F_WRLCK, F_SETLKW, 1, len) == 0) {
  • branches/samba-3.5.x/lib/tdb/common/open.c

    r829 r836  
    2727
    2828#include "tdb_private.h"
    29 
    30 #ifdef __OS2__
    31 // nmbd.c sets it to 1
    32 int global_Sem32Add = 0;
    33 #endif
    3429
    3530/* all contexts, to ensure no double-opens (fcntl locks don't nest!) */
     
    184179        tdb->hash_fn = hash_fn ? hash_fn : default_tdb_hash;
    185180
    186 #ifdef __OS2__
    187         if (os2_CrtSem(tdb, name, "tdb_open_ex") != 0) {
    188                 goto fail;
    189         }
    190 #endif
    191 
    192181        /* cache the page size */
    193182        tdb->page_size = getpagesize();
     
    262251        if ((tdb_flags & TDB_CLEAR_IF_FIRST) &&
    263252            (!tdb->read_only)
    264 #ifndef __OS2__
    265253            && (locked = (tdb->methods->tdb_brlock(tdb, ACTIVE_LOCK, F_WRLCK, F_SETLK, 0, 1) == 0))
    266 #endif
    267254            ) {
    268255                open_flags |= O_CREAT;
     
    328315        tdb_mmap(tdb);
    329316        if (locked) {
    330 #ifndef __OS2__
    331317                if (tdb->methods->tdb_brlock(tdb, ACTIVE_LOCK, F_UNLCK, F_SETLK, 0, 1) == -1) {
    332318                        TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: "
     
    335321                        goto fail;
    336322                }
    337 
    338 #endif
    339323        }
    340324
     
    343327           users know we're using it. */
    344328
    345 #ifndef __OS2__
    346329        if (tdb_flags & TDB_CLEAR_IF_FIRST) {
    347330                /* leave this lock in place to indicate it's in use */
     
    349332                        goto fail;
    350333        }
    351 #endif
    352334
    353335        /* if needed, run recovery */
     
    355337                goto fail;
    356338        }
    357 
    358 #ifdef __OS2__
    359         // YD internal databases do not get global lock!
    360         if (tdb->methods->tdb_brlock(tdb, GLOBAL_LOCK, F_UNLCK, F_SETLKW, 0, 1) == -1)
    361                 goto fail;
    362 #endif
    363339
    364340#ifdef TDB_TRACE
     
    382358         * do with disk files, and resume here by releasing their
    383359         * global lock and hooking into the active list. */
    384 #ifndef __OS2__
    385360        if (tdb->methods->tdb_brlock(tdb, GLOBAL_LOCK, F_UNLCK, F_SETLKW, 0, 1) == -1)
    386361                goto fail;
    387 #endif
    388362        tdb->next = tdbs;
    389363                tdbs = tdb;
     
    406380        }
    407381        SAFE_FREE(tdb->name);
    408 #ifdef __OS2__
    409         os2_DltSem(tdb, "tdb_open_ex");
    410 #endif
    411382        if (tdb->fd != -1)
    412383                if (close(tdb->fd) != 0)
     
    449420        }
    450421        SAFE_FREE(tdb->name);
    451 #ifdef __OS2__
    452         // YD internal databases do not have a global lock
    453         if (!(tdb->flags & TDB_INTERNAL))
    454                 tdb->methods->tdb_brlock(tdb, GLOBAL_LOCK, F_UNLCK, F_SETLK, 0, 1);
    455 #endif
    456422        if (tdb->fd != -1) {
    457423                ret = close(tdb->fd);
     
    459425        }
    460426        SAFE_FREE(tdb->lockrecs);
    461 #ifdef __OS2__
    462         os2_DltSem(tdb, "tdb_close");   
    463 #endif
    464427
    465428        /* Remove from contexts list */
     
    502465                return 0; /* Nothing to do. */
    503466        }
    504 
    505 #ifdef __OS2__
    506         os2_DltSem(tdb, "tdb_reopen");
    507 
    508         if (os2_CrtSem(tdb, tdb->name, "tdb_reopen") != 0) {
    509                 goto fail;
    510         }
    511 #endif
    512467
    513468        if (tdb->num_locks != 0 || tdb->global_lock.count) {
     
    596551        return 0;
    597552}
    598 
    599 #ifdef __OS2__
    600 int os2_CrtSem(struct tdb_context *tdb, const char *name, const char *caller)
    601 {
    602         // name could be null, so handle it
    603         if (name == NULL) return -1;
    604 
    605         if (!(tdb->flags & TDB_INTERNAL))
    606         {
    607                 char    szSem[_MAX_PATH];
    608                 char    drive[_MAX_DRIVE], dir[_MAX_DIR];
    609                 char    fname[_MAX_FNAME], ext[_MAX_EXT];
    610                 APIRET  rc;
    611                 // extract path info
    612                 _splitpath( name, drive, dir, fname, ext);
    613                 sprintf( szSem, "\\SEM32\\TDB_GL_%s%s%s%i", dir, fname, ext, global_Sem32Add);
    614                 rc = DosCreateMutexSem( szSem, &tdb->hGlobalLock, 0, FALSE);
    615                 if (rc == ERROR_DUPLICATE_NAME)
    616                         rc = DosOpenMutexSem( szSem, &tdb->hGlobalLock);
    617                 if (rc != NO_ERROR) {
    618                                 TDB_LOG((tdb, TDB_DEBUG_ERROR, "cannot open %s %d\n", szSem, rc));
    619                         errno = EINVAL;
    620                         return -1;
    621                 }
    622                 TDB_LOG((tdb, TDB_DEBUG_TRACE,"%s pid %d global handle %d\n", caller, getpid(), tdb->hGlobalLock));
    623 
    624                 sprintf( szSem, "\\SEM32\\TDB_AL_%s%s%s%i", dir, fname, ext, global_Sem32Add);
    625                 rc = DosCreateMutexSem( szSem, &tdb->hActiveLock, 0, FALSE);
    626                 if (rc == ERROR_DUPLICATE_NAME)
    627                         rc = DosOpenMutexSem( szSem, &tdb->hActiveLock);
    628                 if (rc != NO_ERROR) {
    629                         TDB_LOG((tdb, TDB_DEBUG_ERROR, "cannot open %s %d\n", szSem, rc));
    630                         errno = EINVAL;
    631                         return -1;
    632                 }
    633                 TDB_LOG((tdb, TDB_DEBUG_TRACE,"%s pid %d active handle %d\n", caller, getpid(), tdb->hActiveLock));
    634 
    635                 sprintf( szSem, "\\SEM32\\TDB_TL_%s%s%s%i", dir, fname, ext, global_Sem32Add);
    636                 rc = DosCreateMutexSem( szSem, &tdb->hTransactionLock, 0, FALSE);
    637                 if (rc == ERROR_DUPLICATE_NAME)
    638                         rc = DosOpenMutexSem( szSem, &tdb->hTransactionLock);
    639                 if (rc != NO_ERROR) {
    640                         TDB_LOG((tdb, TDB_DEBUG_ERROR, "cannot open %s %d\n", szSem, rc));
    641                         errno = EINVAL;
    642                         return -1;
    643                 }
    644                 TDB_LOG((tdb, TDB_DEBUG_TRACE,"%s pid %d transaction handle %d\n", caller, getpid(), tdb->hTransactionLock));
    645         }
    646         return 0;
    647 }
    648 
    649 int os2_DltSem(struct tdb_context *tdb, const char *caller)
    650 {
    651         DosCloseMutexSem( tdb->hGlobalLock);
    652         tdb->hGlobalLock = 0;
    653         DosCloseMutexSem( tdb->hActiveLock);
    654         tdb->hActiveLock = 0;
    655         DosCloseMutexSem( tdb->hTransactionLock);
    656         tdb->hTransactionLock = 0;
    657 
    658         return 0;
    659 }
    660 #endif
    661                
  • branches/samba-3.5.x/lib/tdb/common/tdb_private.h

    r833 r836  
    2323   License along with this library; if not, see <http://www.gnu.org/licenses/>.
    2424*/
    25 
    26 #ifdef __OS2__
    27 #define INCL_ERRORS
    28 #define INCL_DOS
    29 #include <os2.h>
    30 #endif
    3125
    3226#include "replace.h"
     
    210204#endif
    211205        volatile sig_atomic_t *interrupt_sig_ptr;
    212 #ifdef __OS2__
    213         HMTX    hGlobalLock;
    214         HMTX    hActiveLock;
    215         HMTX    hTransactionLock;
    216 #endif
    217206};
    218207
  • branches/samba-3.5.x/lib/tdb/common/transaction.c

    r657 r836  
    495495        /* get a read lock from the freelist to the end of file. This
    496496           is upgraded to a write lock during the commit */
    497 #ifndef __OS2__ // YD the transation lock is an exclusive lock for us, it is enough.
    498497        if (tdb_brlock(tdb, FREELIST_TOP, F_RDLCK, F_SETLKW, 0, 0) == -1) {
    499498                TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_start: failed to get hash locks\n"));
     
    501500                goto fail;
    502501        }
    503 #endif
    504502
    505503        /* setup a copy of the hash table heads so the hash scan in
     
    533531       
    534532fail:
    535 #ifndef __OS2__ // YD the transation lock is an exclusive lock for us, it is enough.
    536533        tdb_brlock(tdb, FREELIST_TOP, F_UNLCK, F_SETLKW, 0, 0);
    537 #endif
    538534        tdb_transaction_unlock(tdb);
    539535        SAFE_FREE(tdb->transaction->blocks);
     
    636632        tdb->methods = tdb->transaction->io_methods;
    637633
    638 #ifndef __OS2__ // YD the transation lock is an exclusive lock for us, it is enough
    639634        tdb_brlock(tdb, FREELIST_TOP, F_UNLCK, F_SETLKW, 0, 0);
    640 #endif
    641635        tdb_transaction_unlock(tdb);
    642636        SAFE_FREE(tdb->transaction->hash_heads);
     
    946940
    947941        /* upgrade the main transaction lock region to a write lock */
    948 #ifndef __OS2__ // YD the global lock is an exclusive lock for us, it is enough
    949942        if (tdb_brlock_upgrade(tdb, FREELIST_TOP, 0) == -1) {
    950943                TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_prepare_commit: failed to upgrade hash locks\n"));
     
    953946                return -1;
    954947        }
    955 #endif
    956948
    957949        /* get the global lock - this prevents new users attaching to the database
  • branches/samba-3.5.x/source3/nmbd/nmbd.c

    r832 r836  
    2929extern bool rescan_listen_set;
    3030extern bool global_in_nmbd;
    31 
    32 #ifdef __OS2__
    33 extern int global_Sem32Add;
    34 #endif
    3531
    3632extern bool override_logfile;
     
    791787        TALLOC_CTX *frame = talloc_stackframe(); /* Setup tos. */
    792788
    793 #ifdef __OS2__
    794         global_Sem32Add = 1;
    795 #endif
    796 
    797789        load_case_tables();
    798790
Note: See TracChangeset for help on using the changeset viewer.