Changeset 834


Ignore:
Timestamp:
Nov 25, 2013, 4:35:16 PM (12 years ago)
Author:
Silvan Scherrer
Message:

Samba 3.6: use fcntl and friends for locking

Location:
trunk/server
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/server/lib/tdb/common/io.c

    r752 r834  
    9494        // YD we must upgrade read locks to write locks (exclusive), otherwise
    9595        // the owner (us) is not allowed to write to the file (different from unix)
    96         TDB_LOG((tdb, TDB_DEBUG_TRACE,"unlocking at %d len=%d before writing.\n", off, len));
    97         tdb_brunlock( tdb, F_RDLCK, off, len);
    9896        // if a wider previous lock is in effect, we cannot write lock our segment
    9997        // (e.g. a lock_upgrade locks all the file), so we hope the previous lock
    10098        // is a write lock: do not wait for lock.
    101         tdb_brlock( tdb, F_WRLCK, off, len, F_SETLK);
     99        int upgradeLockRC = tdb_brlock( tdb, F_WRLCK, off, len, F_SETLK);
     100        TDB_LOG((tdb, TDB_DEBUG_TRACE,"upgrading lock at %d len=%d "
     101                "before writing %s (rc=%d).\n", off, len,
     102                 upgradeLockRC ? "was successfull":"failed", upgradeLockRC));
    102103#endif
    103 
    104104        if (tdb->map_ptr) {
    105105                memcpy(off + (char *)tdb->map_ptr, buf, len);
     
    127127                                 "write %d bytes at %d in two attempts\n",
    128128                                 len, off));
    129 #ifdef __OS2__ // remove our lock
    130                         tdb_brunlock( tdb, F_WRLCK, off, len);
     129#ifdef __OS2__ // remove our lock, if upgrade succeded
     130                        if (upgradeLockRC == 0)
     131                                tdb_brunlock( tdb, F_WRLCK, off, len);
    131132#endif
    132133                        return -1;
    133134                }
    134135        }
    135 #ifdef __OS2__ // remove our lock
    136                         tdb_brunlock( tdb, F_WRLCK, off, len);
     136#ifdef __OS2__ // remove our lock, if upgrade succeded
     137        if (upgradeLockRC == 0)
     138                tdb_brunlock( tdb, F_WRLCK, off, len);
    137139#endif
    138140        return 0;
  • trunk/server/lib/tdb/common/lock.c

    r830 r834  
    2727
    2828#include "tdb_private.h"
    29 #ifdef __OS2__
    30 
    31 static char* lock_type( bool waitflag)
    32 {
    33         if (waitflag)
    34                 return "F_SETLKW";
    35         else
    36                 return "F_SETLK";
    37 }
    38 
    39 static char* read_type( int rw)
    40 {
    41         static char buffer[16];
    42         switch(rw) {
    43         case F_RDLCK: return "F_RDLCK";
    44         case F_UNLCK: return "F_UNLCK";
    45         case F_WRLCK: return "F_WRLCK";
    46         default:
    47                 sprintf( buffer, "unknown %d", rw);
    48         }
    49         return buffer;
    50 }
    51 
    52 static int _mutex_brlock(struct tdb_context *tdb, tdb_off_t offset,
    53                int rw_type, bool waitflag, size_t len)
    54 {
    55         HMTX    hSem;
    56         ULONG   ulTimeout;
    57         APIRET  rc;
    58        
    59         switch( offset) {
    60         case OPEN_LOCK:
    61                 hSem = tdb->hGlobalLock;
    62                 break;
    63         case ACTIVE_LOCK:
    64                 hSem = tdb->hActiveLock;
    65                 break;
    66         case TRANSACTION_LOCK:
    67                 hSem = tdb->hTransactionLock;
    68                 break;
    69         default:
    70                 TDB_LOG((tdb, TDB_DEBUG_FATAL, "_mutex_brlock unknown offset %d\n", offset));
    71                 exit(1);
    72                 break;
    73         }
    74 
    75         if (hSem == 0) {
    76                 TDB_LOG((tdb, TDB_DEBUG_FATAL, "_mutex_brlock unknown sem handle offset %d\n", offset));
    77                 exit(1);
    78         }
    79 
    80         TDB_LOG((tdb, TDB_DEBUG_TRACE,"_mutex_brlock handle %d, offset %d\n", hSem, offset));
    81 
    82         if (waitflag)
    83                 ulTimeout = SEM_INDEFINITE_WAIT;
    84         else
    85                 ulTimeout = SEM_IMMEDIATE_RETURN;
    86 
    87         switch (rw_type) {
    88         case F_UNLCK:
    89                 rc = DosReleaseMutexSem( hSem);
    90                 break;
    91         case F_RDLCK:
    92         case F_WRLCK:
    93                 rc = DosRequestMutexSem( hSem, ulTimeout);
    94                 break;
    95         default:
    96                 TDB_LOG((tdb, TDB_DEBUG_FATAL, "_mutex_brlock unknown rw_type request %d\n", rw_type));
    97                 exit(1);
    98                 break;
    99         }
    100 
    101         if (rc == NO_ERROR
    102                 || rc == ERROR_SEM_OWNER_DIED
    103                 || rc == ERROR_NOT_OWNER)
    104                 return 0;
    105 
    106         errno = EINVAL;
    107         TDB_LOG(( tdb, TDB_DEBUG_ERROR, "_mutex_brlock pid %d, failed (fd=%d) at offset %d rw_type=%d lck_type=%d len=%d, rc=%d\n",
    108                  getpid(), tdb->fd, offset, rw_type, waitflag, (int)len, rc));
    109         tdb->ecode = TDB_ERR_LOCK;
    110         return -1;
    111 }
    112 #endif
    11329
    11430_PUBLIC_ void tdb_setalarm_sigptr(struct tdb_context *tdb, volatile sig_atomic_t *ptr)
     
    11834
    11935static int fcntl_lock(struct tdb_context *tdb,
    120                       int rw, tdb_off_t off, size_t len, bool waitflag)
    121 {
    122 #ifdef __OS2__
    123         APIRET      rc;
    124         ULONG       fAccess = 0; // default exclusiv
    125         FILELOCK    lockArea = {0}, unlockArea = {0};
    126 
    127         TDB_LOG((tdb, TDB_DEBUG_TRACE, "fcntl_lock in pid %d, fd %d, lck_type %s, rw_type %s, offset %d, len %d\n",
    128                 getpid(), tdb->fd, lock_type(waitflag), read_type(rw), off, len));
    129        
    130         switch(off) {
    131         case OPEN_LOCK:
    132         case ACTIVE_LOCK:
    133         case TRANSACTION_LOCK:
    134                 return _mutex_brlock(tdb, off, rw, waitflag, len);
    135         }
    136 
    137         /* flags and order */
    138         switch (rw)
    139         {
    140                 case F_UNLCK:
    141                         unlockArea.lOffset = off;
    142                         unlockArea.lRange  = len ? len : LONG_MAX;
    143                         break;
    144                 case F_RDLCK:
    145                         lockArea.lOffset = off;
    146                         lockArea.lRange  = len ? len : LONG_MAX;
    147                         fAccess = 1; /* read-only */
    148                         break;
    149                 case F_WRLCK:
    150                         lockArea.lOffset = off;
    151                         lockArea.lRange  = len ? len : LONG_MAX;
    152                         break;
    153                 default:
    154                         break;
    155         }
    156                
    157         rc = DosSetFileLocks(tdb->fd, &unlockArea, &lockArea, SEM_IMMEDIATE_RETURN, fAccess);
    158 
    159         if (rc != NO_ERROR && waitflag) {
    160                 int     count = 20;
    161                 do {
    162                         rc = DosSetFileLocks(tdb->fd, &unlockArea, &lockArea, 100, fAccess);
    163                         count--;
    164                 } while( count>0 && rc !=NO_ERROR);
    165 
    166         }
    167 
    168         TDB_LOG(( tdb, TDB_DEBUG_TRACE, "fcntl_lock out pid %d, fd %d, lck_type %s, rw_type %s, offset %d, len %d, rc=%d\n",
    169                 getpid(), tdb->fd, lock_type(waitflag), read_type(rw), off, len, rc));
    170 
    171         if (rc != NO_ERROR) {
    172                 errno  = EINVAL;
    173                 return -1;
    174         }
    175         return 0;
    176 #else
     36                      int rw, off_t off, off_t len, bool waitflag)
     37{
    17738        struct flock fl;
    17839
     
    18041        fl.l_whence = SEEK_SET;
    18142        fl.l_start = off;
     43#ifdef __OS2__
     44        fl.l_len = len ? len:LONG_MAX;
     45#else
    18246        fl.l_len = len;
     47#endif
    18348        fl.l_pid = 0;
    18449
     
    18752        else
    18853                return fcntl(tdb->fd, F_SETLK, &fl);
    189 #endif
    190 }
    191 
    192 static int fcntl_unlock(struct tdb_context *tdb, int rw, tdb_off_t off, size_t len)
     54}
     55
     56static int fcntl_unlock(struct tdb_context *tdb, int rw, off_t off, off_t len)
    19357{
    19458        struct flock fl;
     
    254118        fl.l_whence = SEEK_SET;
    255119        fl.l_start = off;
     120#ifdef __OS2__
     121        fl.l_len = len ? len:LONG_MAX;
     122#else
    256123        fl.l_len = len;
     124#endif
    257125        fl.l_pid = 0;
     126
    258127#ifdef __OS2__
    259         int rc = 0;
    260         rc = fcntl_lock(tdb, F_UNLCK, off, len, 1);
     128        int rc = fcntl(tdb->fd, F_SETLKW, &fl);
    261129        // if the first unlock doesn't work and it's a complete unlock,
    262130        // we split it in 2 parts. first hash size*4 and then the rest
    263131        // as it was locked that way as well. and it seems fcntl() doesn't care
    264132        if (rc != 0 && off == FREELIST_TOP && len == 0) {
    265                 rc = fcntl_lock(tdb, F_UNLCK, off, tdb->header.hash_size *4, 1);
    266                 if (rc == 0)
    267                         rc = fcntl_lock(tdb, F_UNLCK, (off + tdb->header.hash_size *4), len, 1);
     133                fl.l_len = tdb->header.hash_size * 4;
     134                rc = fcntl(tdb->fd, F_SETLKW, &fl);
     135                if (rc == 0) {
     136                        fl.l_start = off + tdb->header.hash_size * 4;
     137                        fl.l_len = LONG_MAX;
     138                        rc = fcntl(tdb->fd, F_SETLKW, &fl);
     139                }
    268140        }
    269141        return rc;
     
    376248        while (count--) {
    377249                struct timeval tv;
    378 #ifdef __OS2__
    379                 // YD we cannot upgrade without an unlock first...
    380                 tdb_brlock(tdb, F_UNLCK, FREELIST_TOP, 0, TDB_LOCK_WAIT|TDB_LOCK_PROBE);
    381 #endif
    382250                if (tdb_brlock(tdb, F_WRLCK, FREELIST_TOP, 0,
    383251                               TDB_LOCK_WAIT|TDB_LOCK_PROBE) == 0) {
  • trunk/server/lib/tdb/common/open.c

    r825 r834  
    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!) */
     
    242237        }
    243238
    244 #ifdef __OS2__
    245         if (os2_CrtSem(tdb, "tdb_open_ex") != 0) {
    246                 goto fail;
    247         }
    248 #endif
    249239        /* cache the page size */
    250240        tdb->page_size = getpagesize();
     
    322312        /* we need to zero database if we are the only one with it open */
    323313        if ((tdb_flags & TDB_CLEAR_IF_FIRST) &&
    324 #ifndef __OS2__
    325314            (!tdb->read_only) &&
    326315            (locked = (tdb_nest_lock(tdb, ACTIVE_LOCK, F_WRLCK, TDB_LOCK_NOWAIT|TDB_LOCK_PROBE) == 0))) {
    327 #else
    328             (!tdb->read_only) ) {
    329 #endif
    330316                int ret;
    331317                ret = tdb_brlock(tdb, F_WRLCK, FREELIST_TOP, 0,
     
    429415        tdb_mmap(tdb);
    430416        if (locked) {
    431 #ifndef __OS2__
    432417                if (tdb_nest_unlock(tdb, ACTIVE_LOCK, F_WRLCK, false) == -1) {
    433418                        TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: "
     
    437422                }
    438423
    439 #endif
    440424        }
    441425
     
    444428           users know we're using it. */
    445429
    446 #ifndef __OS2__
    447430        if (tdb_flags & TDB_CLEAR_IF_FIRST) {
    448431                /* leave this lock in place to indicate it's in use */
     
    451434                }
    452435        }
    453 #endif
    454436
    455437        /* if needed, run recovery */
     
    457439                goto fail;
    458440        }
    459 
    460 #ifdef __OS2__
    461         // YD internal databases do not get global lock!
    462         if (tdb_nest_unlock(tdb, OPEN_LOCK, F_WRLCK, false) == -1)
    463                 goto fail;
    464 #endif
    465441
    466442#ifdef TDB_TRACE
     
    484460         * do with disk files, and resume here by releasing their
    485461         * open lock and hooking into the active list. */
    486 #ifndef __OS2__
    487462        if (tdb_nest_unlock(tdb, OPEN_LOCK, F_WRLCK, false) == -1) {
    488463                goto fail;
    489464        }
    490 #endif
    491465        tdb->next = tdbs;
    492466        tdbs = tdb;
     
    511485                if (close(tdb->fd) != 0)
    512486                        TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_open_ex: failed to close tdb->fd on error!\n"));
    513 #ifdef __OS2__
    514         os2_DltSem(tdb, "tdb_open_ex");
    515 #endif
    516487        SAFE_FREE(tdb->lockrecs);
    517488        SAFE_FREE(tdb->name);
     
    553524        }
    554525        SAFE_FREE(tdb->name);
    555 #ifdef __OS2__
    556         // YD internal databases do not have a global lock
    557         if (!(tdb->flags & TDB_INTERNAL))
    558         tdb_nest_unlock(tdb, OPEN_LOCK, F_WRLCK, false);
    559 #endif
    560526        if (tdb->fd != -1) {
    561527                ret = close(tdb->fd);
     
    564530        SAFE_FREE(tdb->lockrecs);
    565531
    566 #ifdef __OS2__
    567         os2_DltSem(tdb, "tdb_close");   
    568 #endif
    569532        /* Remove from contexts list */
    570533        for (i = &tdbs; *i; i = &(*i)->next) {
     
    606569                return 0; /* Nothing to do. */
    607570        }
    608 
    609 #ifdef __OS2__
    610         os2_DltSem(tdb, "tdb_reopen");
    611 
    612         if (os2_CrtSem(tdb, "tdb_reopen") != 0) {
    613                 goto fail;
    614         }
    615 #endif
    616571
    617572        if (tdb_have_extra_locks(tdb)) {
     
    703658        return 0;
    704659}
    705 
    706 #ifdef __OS2__
    707 int os2_CrtSem(struct tdb_context *tdb, const char *caller)
    708 {
    709         // tbd->name could be null, so handle it
    710         if (tdb->name == NULL) return -1;
    711        
    712         if (!(tdb->flags & TDB_INTERNAL))
    713         {
    714                 char    szSem[_MAX_PATH];
    715                 char    drive[_MAX_DRIVE], dir[_MAX_DIR];
    716                 char    fname[_MAX_FNAME], ext[_MAX_EXT];
    717                 APIRET  rc;
    718                 // extract path info
    719                 _splitpath( tdb->name, drive, dir, fname, ext);
    720                 sprintf( szSem, "\\SEM32\\TDB_OL_%s%s%s%i", dir, fname, ext, global_Sem32Add);
    721                 rc = DosCreateMutexSem( szSem, &tdb->hGlobalLock, 0, FALSE);
    722                 if (rc == ERROR_DUPLICATE_NAME)
    723                         rc = DosOpenMutexSem( szSem, &tdb->hGlobalLock);
    724                 if (rc != NO_ERROR) {
    725                                 TDB_LOG((tdb, TDB_DEBUG_ERROR, "cannot open %s %d\n", szSem, rc));
    726                         errno = EINVAL;
    727                         return -1;
    728                 }
    729                 TDB_LOG((tdb, TDB_DEBUG_TRACE,"%s pid %d open handle %d\n", caller, getpid(), tdb->hGlobalLock));
    730 
    731                 sprintf( szSem, "\\SEM32\\TDB_AL_%s%s%s%i", dir, fname, ext, global_Sem32Add);
    732                 rc = DosCreateMutexSem( szSem, &tdb->hActiveLock, 0, FALSE);
    733                 if (rc == ERROR_DUPLICATE_NAME)
    734                         rc = DosOpenMutexSem( szSem, &tdb->hActiveLock);
    735                 if (rc != NO_ERROR) {
    736                         TDB_LOG((tdb, TDB_DEBUG_ERROR, "cannot open %s %d\n", szSem, rc));
    737                         errno = EINVAL;
    738                         return -1;
    739                 }
    740                 TDB_LOG((tdb, TDB_DEBUG_TRACE,"%s pid %d active handle %d\n", caller, getpid(), tdb->hActiveLock));
    741 
    742                 sprintf( szSem, "\\SEM32\\TDB_TL_%s%s%s%i", dir, fname, ext, global_Sem32Add);
    743                 rc = DosCreateMutexSem( szSem, &tdb->hTransactionLock, 0, FALSE);
    744                 if (rc == ERROR_DUPLICATE_NAME)
    745                         rc = DosOpenMutexSem( szSem, &tdb->hTransactionLock);
    746                 if (rc != NO_ERROR) {
    747                         TDB_LOG((tdb, TDB_DEBUG_ERROR, "cannot open %s %d\n", szSem, rc));
    748                         errno = EINVAL;
    749                         return -1;
    750                 }
    751                 TDB_LOG((tdb, TDB_DEBUG_TRACE,"%s pid %d transaction handle %d\n", caller, getpid(), tdb->hTransactionLock));
    752         }
    753         return 0;
    754 }
    755 
    756 int os2_DltSem(struct tdb_context *tdb, const char *caller)
    757 {
    758         DosCloseMutexSem( tdb->hGlobalLock);
    759         tdb->hGlobalLock = 0;
    760         DosCloseMutexSem( tdb->hActiveLock);
    761         tdb->hActiveLock = 0;
    762         DosCloseMutexSem( tdb->hTransactionLock);
    763         tdb->hTransactionLock = 0;
    764 
    765         return 0;
    766 }
    767 #endif
  • trunk/server/lib/tdb/common/tdb_private.h

    r745 r834  
    2323   License along with this library; if not, see <http://www.gnu.org/licenses/>.
    2424*/
    25 #ifdef __OS2__
    26 #define INCL_ERRORS
    27 #define INCL_DOS
    28 #include <os2.h>
    29 #endif
    3025
    3126#include "replace.h"
     
    219214#endif
    220215        volatile sig_atomic_t *interrupt_sig_ptr;
    221 #ifdef __OS2__
    222         HMTX    hGlobalLock;
    223         HMTX    hActiveLock;
    224         HMTX    hTransactionLock;
    225 #endif
    226216};
    227217
  • trunk/server/lib/tdb/common/transaction.c

    r745 r834  
    486486        /* get a read lock from the freelist to the end of file. This
    487487           is upgraded to a write lock during the commit */
    488 #ifndef __OS2__ // YD the transation lock is an exclusive lock for us, it is enough.
    489488        if (tdb_allrecord_lock(tdb, F_RDLCK, TDB_LOCK_WAIT, true) == -1) {
    490489                TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_start: failed to get hash locks\n"));
    491490                goto fail_allrecord_lock;
    492491        }
    493 #endif
    494492
    495493        /* setup a copy of the hash table heads so the hash scan in
     
    523521
    524522fail:
    525 #ifndef __OS2__ // YD the transation lock is an exclusive lock for us, it is enough.
    526523        tdb_allrecord_unlock(tdb, F_RDLCK, false);
    527 #endif
    528524fail_allrecord_lock:
    529525        tdb_transaction_unlock(tdb, F_WRLCK);
     
    949945
    950946        /* upgrade the main transaction lock region to a write lock */
    951 #ifndef __OS2__ // YD the global lock is an exclusive lock for us, it is enough
    952947        if (tdb_allrecord_upgrade(tdb) == -1) {
    953948                TDB_LOG((tdb, TDB_DEBUG_ERROR, "tdb_transaction_prepare_commit: failed to upgrade hash locks\n"));
     
    955950                return -1;
    956951        }
    957 #endif
    958952
    959953        /* get the open lock - this prevents new users attaching to the database
  • trunk/server/lib/util/genrand.c

    r745 r834  
    257257
    258258#ifdef __OS2__
    259                 os2_randget(md4_buf, sizeof(md4_buf));
     259                os2_randget(md4_buf, sizeof(md4_buf));
    260260#else
    261261                get_random_stream(md4_buf, sizeof(md4_buf));
  • trunk/server/source3/nmbd/nmbd.c

    r757 r834  
    3333extern bool rescan_listen_set;
    3434extern bool global_in_nmbd;
    35 
    36 #ifdef __OS2__
    37 extern int global_Sem32Add;
    38 #endif
    3935
    4036extern bool override_logfile;
     
    398394                SAFE_FREE(lfile);
    399395#endif
    400 
    401396        return(ret);
    402397}
     
    791786        frame = talloc_stackframe();
    792787
    793 #ifdef __OS2__
    794         global_Sem32Add = 1;
    795 #endif
    796 
    797788        load_case_tables();
    798789
Note: See TracChangeset for help on using the changeset viewer.