Add a timeout to tdb_lock_bystring(). Ensure we never have more than
authorJeremy Allison <jra@samba.org>
Fri, 4 Oct 2002 22:53:30 +0000 (22:53 +0000)
committerJeremy Allison <jra@samba.org>
Fri, 4 Oct 2002 22:53:30 +0000 (22:53 +0000)
MAX_PRINT_JOBS in a queue.
Jeremy.
(This used to be commit bb58a08af459b4abae9d53ab98c15f40638ce52b)

12 files changed:
source3/groupdb/mapping.c
source3/include/local.h
source3/include/printing.h
source3/lib/account_pol.c
source3/param/loadparm.c
source3/passdb/secrets.c
source3/printing/nt_printing.c
source3/printing/printing.c
source3/rpc_server/srv_srvsvc_nt.c
source3/tdb/tdb.c
source3/tdb/tdb.h
source3/tdb/tdbutil.c

index 56414312465446b02e2e855e2b02bfa879dbdd4e..0f05316949a1894b75a7a5ada4689cd1cd15f4e7 100644 (file)
@@ -223,7 +223,7 @@ static BOOL init_group_mapping(void)
        local_pid = sys_getpid();
 
        /* handle a Samba upgrade */
-       tdb_lock_bystring(tdb, vstring);
+       tdb_lock_bystring(tdb, vstring, 0);
 
        /* Cope with byte-reversed older versions of the db. */
        vers_id = tdb_fetch_int32(tdb, vstring);
index 5096e13fc3931230f64dbf445440d159315cd0f4..2be9c1e1017409f5e907097cd6dabd23bd7ab485 100644 (file)
 /* this enables the "rabbit pellet" fix for SMBwritebraw */
 #define RABBIT_PELLET_FIX 1
 
+/* Max number of jobs per print queue. */
+#define PRINT_MAX_JOBID 10000
+
 #endif
index 9774a6acd95d401c4195e910d2abed79cbcd5880..38ff7eac36695628f15358c904df907794b5d0ff 100644 (file)
@@ -65,7 +65,7 @@ extern struct printif generic_printif;
 extern struct printif  cups_printif;
 #endif /* HAVE_CUPS */
 
-#define PRINT_MAX_JOBID 10000
+/* PRINT_MAX_JOBID is now defined in local.h */
 #define UNIX_JOB_START PRINT_MAX_JOBID
 #define NEXT_JOBID(j) ((j+1) % PRINT_MAX_JOBID > 0 ? (j+1) % PRINT_MAX_JOBID : 1)
 
index b5f205c508687628aed45abade2f8eb6921a6d94..6f51c916d719657e79994edf9a0ab2e3f0e68c77 100644 (file)
@@ -45,7 +45,7 @@ BOOL init_account_policy(void)
        local_pid = sys_getpid();
 
        /* handle a Samba upgrade */
-       tdb_lock_bystring(tdb, vstring);
+       tdb_lock_bystring(tdb, vstring,0);
        if (!tdb_fetch_uint32(tdb, vstring, &version) || version != DATABASE_VERSION) {
                tdb_traverse(tdb, tdb_traverse_delete_fn, NULL);
                tdb_store_uint32(tdb, vstring, DATABASE_VERSION);
index 18cba172c090aa713bf3b26b14f3daa631d7ace6..ba0866883fe3f3af7137a9ca2b9b57e4c0f0b40f 100644 (file)
@@ -1798,7 +1798,6 @@ FN_LOCAL_INTEGER(lp_force_dir_security_mode, iDir_Security_force_mode)
 FN_LOCAL_INTEGER(lp_max_connections, iMaxConnections)
 FN_LOCAL_INTEGER(lp_defaultcase, iDefaultCase)
 FN_LOCAL_INTEGER(lp_minprintspace, iMinPrintSpace)
-FN_LOCAL_INTEGER(lp_maxprintjobs, iMaxPrintJobs)
 FN_LOCAL_INTEGER(lp_printing, iPrinting)
 FN_LOCAL_INTEGER(lp_oplock_contention_limit, iOplockContentionLimit)
 FN_LOCAL_INTEGER(lp_csc_policy, iCSCPolicy)
@@ -4070,3 +4069,16 @@ const char *get_called_name(void)
 
        return local_machine;
 }
+
+/*******************************************************************
+ Return the max print jobs per queue.
+********************************************************************/
+
+int lp_maxprintjobs(int snum)
+{
+       int maxjobs = LP_SNUM_OK(snum) ? ServicePtrs[snum]->iMaxPrintJobs : sDefault.iMaxPrintJobs;
+       if (maxjobs <= 0 || maxjobs >= PRINT_MAX_JOBID)
+               maxjobs = PRINT_MAX_JOBID - 1;
+
+       return maxjobs;
+}
index 4b2c76d8b0ec8124b944399e3327354389b930e7..ad56fcedd18208a426f096c242cbb47a0835f0fd 100644 (file)
@@ -215,7 +215,7 @@ BOOL secrets_lock_trust_account_password(char *domain, BOOL dolock)
                return False;
 
        if (dolock)
-               return (tdb_lock_bystring(tdb, trust_keystr(domain)) == 0);
+               return (tdb_lock_bystring(tdb, trust_keystr(domain),0) == 0);
        else
                tdb_unlock_bystring(tdb, trust_keystr(domain));
        return True;
@@ -579,69 +579,31 @@ NTSTATUS secrets_get_trusted_domains(TALLOC_CTX* ctx, int* enum_ctx, int max_num
        return status;
 }
 
-static SIG_ATOMIC_T gotalarm;
+/*******************************************************************************
+ Lock the secrets tdb based on a string - this is used as a primitive form of mutex
+ between smbd instances.
+*******************************************************************************/
 
-/***************************************************************
- Signal function to tell us we timed out.
-****************************************************************/
-
-static void gotalarm_sig(void)
-{
-       gotalarm = 1;
-}
-
-/*
-  lock the secrets tdb based on a string - this is used as a primitive form of mutex
-  between smbd instances. 
-*/
 BOOL secrets_named_mutex(const char *name, unsigned int timeout)
 {
-       TDB_DATA key;
        int ret;
 
        if (!message_init())
                return False;
 
-       key.dptr = (char *)name;
-       key.dsize = strlen(name)+1;
-
-       /* Allow tdb_chainlock to be interrupted by an alarm. */
-       gotalarm = 0;
-       tdb_set_lock_alarm(&gotalarm);
-
-       if (timeout) {
-               CatchSignal(SIGALRM, SIGNAL_CAST gotalarm_sig);
-               alarm(timeout);
-       }
-
-       ret = tdb_chainlock(tdb, key);
-
-       /* Prevent tdb_chainlock from being interrupted by an alarm. */
-       tdb_set_lock_alarm(NULL);
-
-       if (timeout) {
-               alarm(0);
-               CatchSignal(SIGALRM, SIGNAL_CAST SIG_IGN);
-               if (gotalarm)
-                       return False;
-       }
-
+       ret = tdb_lock_bystring(tdb, name, timeout);
        if (ret == 0)
                DEBUG(10,("secrets_named_mutex: got mutex for %s\n", name ));
 
        return (ret == 0);
 }
 
-/*
-  unlock a named mutex
-*/
+/*******************************************************************************
+ Unlock a named mutex.
+*******************************************************************************/
+
 void secrets_named_mutex_release(char *name)
 {
-       TDB_DATA key;
-
-       key.dptr = name;
-       key.dsize = strlen(name)+1;
-
-       tdb_chainunlock(tdb, key);
+       tdb_unlock_bystring(tdb, name);
        DEBUG(10,("secrets_named_mutex: released mutex for %s\n", name ));
 }
index 58eba9d87e8cd4ef014965b54c20c85222d4583b..fcb493a614895de15358e08805e1033a57d5d770 100644 (file)
@@ -287,7 +287,7 @@ BOOL nt_printing_init(void)
        local_pid = sys_getpid();
  
        /* handle a Samba upgrade */
-       tdb_lock_bystring(tdb_drivers, vstring);
+       tdb_lock_bystring(tdb_drivers, vstring, 0);
        {
                int32 vers_id;
 
@@ -362,7 +362,7 @@ uint32 update_c_setprinter(BOOL initialize)
        int32 c_setprinter;
        int32 printer_count = 0;
  
-       tdb_lock_bystring(tdb_printers, GLOBAL_C_SETPRINTER);
+       tdb_lock_bystring(tdb_printers, GLOBAL_C_SETPRINTER, 0);
  
        /* Traverse the tdb, counting the printers */
        tdb_traverse(tdb_printers, traverse_counting_printers, (void *)&printer_count);
index 6474c92c692c5a16cd6a64fc0bcb01bc94a3985a..91851a37f8aa4cc82b42e8005f4e02734ae94e70 100644 (file)
@@ -257,7 +257,7 @@ BOOL print_backend_init(void)
                pdb = get_print_db_byname(lp_const_servicename(snum));
                if (!pdb)
                        continue;
-               if (tdb_lock_bystring(pdb->tdb, sversion) == -1) {
+               if (tdb_lock_bystring(pdb->tdb, sversion, 0) == -1) {
                        DEBUG(0,("print_backend_init: Failed to open printer %s database\n", lp_const_servicename(snum) ));
                        return False;
                }
@@ -883,7 +883,8 @@ static void print_queue_update(int snum)
        /* Lock the queue for the database update */
 
        slprintf(keystr, sizeof(keystr) - 1, "LOCK/%s", printer_name);
-       if (tdb_lock_bystring(pdb->tdb, keystr) == -1) {
+       /* Only wait 10 seconds for this. */
+       if (tdb_lock_bystring(pdb->tdb, keystr, 10) == -1) {
                DEBUG(0,("print_queue_update: Failed to lock printer %s database\n", printer_name));
                release_print_db(pdb);
                return;
@@ -1380,9 +1381,8 @@ static int get_queue_status(int snum, print_status_struct *status)
        data = tdb_fetch(pdb->tdb, key);
        release_print_db(pdb);
        if (data.dptr) {
-               if (data.dsize == sizeof(print_status_struct)) {
+               if (data.dsize == sizeof(print_status_struct))
                        memcpy(status, data.dptr, sizeof(print_status_struct));
-               }
                SAFE_FREE(data.dptr);
        }
        return status->qcount;
@@ -1465,7 +1465,7 @@ uint32 print_job_start(struct current_user *user, int snum, char *jobname, NT_DE
        }
 
        /* Insure the maximum queue size is not violated */
-       if (lp_maxprintjobs(snum) && (njobs = print_queue_length(snum,NULL)) > lp_maxprintjobs(snum)) {
+       if ((njobs = print_queue_length(snum,NULL)) > lp_maxprintjobs(snum)) {
                DEBUG(3, ("print_job_start: number of jobs (%d) larger than max printjobs per queue (%d).\n",
                        njobs, lp_maxprintjobs(snum) ));
                release_print_db(pdb);
@@ -1473,8 +1473,8 @@ uint32 print_job_start(struct current_user *user, int snum, char *jobname, NT_DE
                return (uint32)-1;
        }
 
-       /* Lock the database */
-       if (tdb_lock_bystring(pdb->tdb, "INFO/nextjob") == -1) {
+       /* Lock the database - only wait 20 seconds. */
+       if (tdb_lock_bystring(pdb->tdb, "INFO/nextjob", 20) == -1) {
                DEBUG(0,("print_job_start: failed to lock printing database %s\n", printername ));
                release_print_db(pdb);
                return (uint32)-1;
index 69945b50b8485b6823c7d63975349f094be3ffa6..ecde51df9f91e3361bd8c6b8a1347fd7cd04919d 100644 (file)
@@ -145,7 +145,7 @@ BOOL share_info_db_init(void)
        local_pid = sys_getpid();
  
        /* handle a Samba upgrade */
-       tdb_lock_bystring(share_tdb, vstring);
+       tdb_lock_bystring(share_tdb, vstring, 0);
 
        /* Cope with byte-reversed older versions of the db. */
        vers_id = tdb_fetch_int32(share_tdb, vstring);
index 4143ac7781900cdbd5f1ad2c7fc82d5ba346f1a3..c57d23cb6f519bf54f9507a887694ecdb9a56bd3 100644 (file)
@@ -208,6 +208,10 @@ static int tdb_brlock(TDB_CONTEXT *tdb, tdb_off offset,
                        TDB_LOG((tdb, 5,"tdb_brlock failed (fd=%d) at offset %d rw_type=%d lck_type=%d\n", 
                                 tdb->fd, offset, rw_type, lck_type));
                }
+               /* Was it an alarm timeout ? */
+               if (errno == EINTR && palarm_fired && *palarm_fired)
+                       return TDB_ERRCODE(TDB_ERR_LOCK_TIMEOUT, -1);
+               /* Otherwise - generic lock error. */
                /* errno set by fcntl */
                return TDB_ERRCODE(TDB_ERR_LOCK, -1);
        }
index 42b88aeb161e36f3002782f19031e70e4596d28a..dda89d035595de97fbe767f528f9335db26c696b 100644 (file)
@@ -44,7 +44,7 @@ extern "C" {
 
 /* error codes */
 enum TDB_ERROR {TDB_SUCCESS=0, TDB_ERR_CORRUPT, TDB_ERR_IO, TDB_ERR_LOCK, 
-               TDB_ERR_OOM, TDB_ERR_EXISTS, TDB_ERR_NOEXIST, TDB_ERR_NOLOCK };
+               TDB_ERR_OOM, TDB_ERR_EXISTS, TDB_ERR_NOEXIST, TDB_ERR_NOLOCK, TDB_ERR_LOCK_TIMEOUT };
 
 #ifndef u32
 #define u32 unsigned
index 1a3a8bb9a52dedfb31f55b88e3a67a17873701f7..e7650033b87b9559e143c7273d11ff54b2f8e5d8 100644 (file)
 /* these are little tdb utility functions that are meant to make
    dealing with a tdb database a little less cumbersome in Samba */
 
+static SIG_ATOMIC_T gotalarm;
+
+/***************************************************************
+ Signal function to tell us we timed out.
+****************************************************************/
+
+static void gotalarm_sig(void)
+{
+       gotalarm = 1;
+}
+
+/****************************************************************************
+ Lock a chain with timeout (in seconds).
+****************************************************************************/
+
+int tdb_chainlock_with_timeout( TDB_CONTEXT *tdb, TDB_DATA key, unsigned int timeout)
+{
+       /* Allow tdb_chainlock to be interrupted by an alarm. */
+       int ret;
+       gotalarm = 0;
+       tdb_set_lock_alarm(&gotalarm);
+
+       if (timeout) {
+               CatchSignal(SIGALRM, SIGNAL_CAST gotalarm_sig);
+               alarm(timeout);
+       }
+
+       ret = tdb_chainlock(tdb, key);
+
+       if (timeout) {
+               alarm(0);
+               CatchSignal(SIGALRM, SIGNAL_CAST SIG_IGN);
+               if (gotalarm)
+                       return -1;
+       }
+
+       return ret;
+}
+
 /****************************************************************************
- Lock a chain by string.
+ Lock a chain by string. Return -1 if timeout or lock failed.
 ****************************************************************************/
 
-int tdb_lock_bystring(TDB_CONTEXT *tdb, char *keyval)
+int tdb_lock_bystring(TDB_CONTEXT *tdb, char *keyval, unsigned int timeout)
 {
        TDB_DATA key;
 
        key.dptr = keyval;
        key.dsize = strlen(keyval)+1;
        
-       return tdb_chainlock(tdb, key);
+       return tdb_chainlock_with_timeout(tdb, key, timeout);
 }
 
 /****************************************************************************
@@ -230,7 +269,7 @@ int32 tdb_change_int32_atomic(TDB_CONTEXT *tdb, char *keystr, int32 *oldval, int
        int32 val;
        int32 ret = -1;
 
-       if (tdb_lock_bystring(tdb, keystr) == -1)
+       if (tdb_lock_bystring(tdb, keystr,0) == -1)
                return -1;
 
        if ((val = tdb_fetch_int32(tdb, keystr)) == -1) {
@@ -271,7 +310,7 @@ BOOL tdb_change_uint32_atomic(TDB_CONTEXT *tdb, char *keystr, uint32 *oldval, ui
        uint32 val;
        BOOL ret = False;
 
-       if (tdb_lock_bystring(tdb, keystr) == -1)
+       if (tdb_lock_bystring(tdb, keystr,0) == -1)
                return False;
 
        if (!tdb_fetch_uint32(tdb, keystr, &val)) {