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);
/* 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
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)
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);
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)
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;
+}
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;
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 ));
}
local_pid = sys_getpid();
/* handle a Samba upgrade */
- tdb_lock_bystring(tdb_drivers, vstring);
+ tdb_lock_bystring(tdb_drivers, vstring, 0);
{
int32 vers_id;
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);
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;
}
/* 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;
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;
}
/* 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);
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;
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);
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);
}
/* 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
/* 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);
}
/****************************************************************************
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) {
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)) {