summaryrefslogtreecommitdiff
path: root/source3/printing/printing.c
diff options
context:
space:
mode:
authorGerald Carter <jerry@samba.org>2004-12-01 20:11:31 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 10:53:28 -0500
commit90bd2b4fd0e57e98ca97bb3a170c079fabd13bef (patch)
tree540f39d397b3bebadd35396453e0922bf43025b1 /source3/printing/printing.c
parentbd4391033113abc592b1a29b53eaa6d7415bb28e (diff)
downloadsamba-90bd2b4fd0e57e98ca97bb3a170c079fabd13bef.tar.gz
samba-90bd2b4fd0e57e98ca97bb3a170c079fabd13bef.tar.bz2
samba-90bd2b4fd0e57e98ca97bb3a170c079fabd13bef.zip
r4028: * prevent the background LPQ daemon from updating
the print queue cache just because multiple smbd processes sent a message that it was out of date. * add some extra debug messages while trying to track down down jobs being left in the queue after printing has completed. (This used to be commit a64505d52fcb23374711e22b3df328c9a7848b84)
Diffstat (limited to 'source3/printing/printing.c')
-rw-r--r--source3/printing/printing.c148
1 files changed, 85 insertions, 63 deletions
diff --git a/source3/printing/printing.c b/source3/printing/printing.c
index ca83945065..9d9ebba950 100644
--- a/source3/printing/printing.c
+++ b/source3/printing/printing.c
@@ -43,10 +43,12 @@ static BOOL remove_from_jobs_changed(const char* sharename, uint32 jobid);
jobids are assigned when a job starts spooling.
*/
-/***************************************************************************
- Nightmare. LANMAN jobid's are 16 bit numbers..... We must map them to 32
- bit RPC jobids.... JRA.
-***************************************************************************/
+struct print_queue_update_context {
+ fstring sharename;
+ enum printing_types printing_type;
+ pstring lpqcommand;
+};
+
static TDB_CONTEXT *rap_tdb;
static uint16 next_rap_jobid;
@@ -55,6 +57,11 @@ struct rap_jobid_key {
uint32 jobid;
};
+/***************************************************************************
+ Nightmare. LANMAN jobid's are 16 bit numbers..... We must map them to 32
+ bit RPC jobids.... JRA.
+***************************************************************************/
+
uint16 pjobid_to_rap(const char* sharename, uint32 jobid)
{
uint16 rap_jobid;
@@ -837,7 +844,7 @@ static pid_t get_updating_pid(fstring sharename)
in the tdb.
****************************************************************************/
-static void set_updating_pid(const fstring sharename, BOOL delete)
+static void set_updating_pid(const fstring sharename, BOOL updating)
{
fstring keystr;
TDB_DATA key;
@@ -853,8 +860,12 @@ static void set_updating_pid(const fstring sharename, BOOL delete)
slprintf(keystr, sizeof(keystr)-1, "UPDATING/%s", sharename);
key.dptr = keystr;
key.dsize = strlen(keystr);
+
+ DEBUG(5, ("set_updating_pid: %s updating lpq cache for print share %s\n",
+ updating ? "" : "not ",
+ sharename ));
- if (delete) {
+ if ( !updating ) {
tdb_delete(pdb->tdb, key);
release_print_db(pdb);
return;
@@ -978,11 +989,46 @@ static void check_job_changed(const char *sharename, TDB_DATA data, uint32 jobid
}
}
-struct print_queue_update_context {
- fstring sharename;
- enum printing_types printing_type;
- pstring lpqcommand;
-};
+/****************************************************************************
+ Check if the print queue has been updated recently enough.
+****************************************************************************/
+
+static BOOL print_cache_expired(const char *sharename)
+{
+ fstring key;
+ time_t last_qscan_time, time_now = time(NULL);
+ struct tdb_print_db *pdb = get_print_db_byname(sharename);
+
+ if (!pdb)
+ return False;
+
+ slprintf(key, sizeof(key), "CACHE/%s", sharename);
+ last_qscan_time = (time_t)tdb_fetch_int32(pdb->tdb, key);
+
+ /*
+ * Invalidate the queue for 3 reasons.
+ * (1). last queue scan time == -1.
+ * (2). Current time - last queue scan time > allowed cache time.
+ * (3). last queue scan time > current time + MAX_CACHE_VALID_TIME (1 hour by default).
+ * This last test picks up machines for which the clock has been moved
+ * forward, an lpq scan done and then the clock moved back. Otherwise
+ * that last lpq scan would stay around for a loooong loooong time... :-). JRA.
+ */
+
+ if (last_qscan_time == ((time_t)-1)
+ || (time_now - last_qscan_time) >= lp_lpqcachetime()
+ || last_qscan_time > (time_now + MAX_CACHE_VALID_TIME))
+ {
+ DEBUG(3, ("print cache expired for queue %s "
+ "(last_qscan_time = %d, time now = %d, qcachetime = %d)\n",
+ sharename, (int)last_qscan_time, (int)time_now,
+ (int)lp_lpqcachetime() ));
+ release_print_db(pdb);
+ return True;
+ }
+ release_print_db(pdb);
+ return False;
+}
/****************************************************************************
main work for updating the lpq cahe for a printer queue
@@ -1003,12 +1049,20 @@ static void print_queue_update_internal( const char *sharename,
fstring keystr, cachestr;
struct tdb_print_db *pdb = get_print_db_byname(sharename);
+ DEBUG(5,("print_queue_update_internal: printer = %s, type = %d, lpq command = [%s]\n",
+ sharename, current_printif->type, lpq_command));
+
+ if ( !print_cache_expired(sharename) ) {
+ DEBUG(5,("print_queue_update_internal: print cache for %s is still ok\n", sharename));
+ return;
+ }
+
/*
* Update the cache time FIRST ! Stops others even
* attempting to get the lock and doing this
* if the lpq takes a long time.
*/
-
+
slprintf(cachestr, sizeof(cachestr)-1, "CACHE/%s", sharename);
tdb_store_int32(pdb->tdb, cachestr, (int)time(NULL));
@@ -1019,8 +1073,8 @@ static void print_queue_update_internal( const char *sharename,
current_printif->type,
lpq_command, &queue, &status);
- DEBUG(3, ("%d job%s in queue for %s\n", qcount, (qcount != 1) ?
- "s" : "", sharename));
+ DEBUG(3, ("print_queue_update_internal: %d job%s in queue for %s\n",
+ qcount, (qcount != 1) ? "s" : "", sharename));
/* Sort the queue by submission time otherwise they are displayed
in hash order. */
@@ -1084,14 +1138,14 @@ static void print_queue_update_internal( const char *sharename,
SAFE_FREE(tstruct.queue);
- DEBUG(10,("print_queue_update: printer %s INFO/total_jobs = %d\n",
+ DEBUG(10,("print_queue_update_internal: printer %s INFO/total_jobs = %d\n",
sharename, tstruct.total_jobs ));
tdb_store_int32(pdb->tdb, "INFO/total_jobs", tstruct.total_jobs);
get_queue_status(sharename, &old_status);
if (old_status.qcount != qcount)
- DEBUG(10,("print_queue_update: queue status change %d jobs -> %d jobs for printer %s\n",
+ DEBUG(10,("print_queue_update_internal: queue status change %d jobs -> %d jobs for printer %s\n",
old_status.qcount, qcount, sharename));
/* store the new queue status structure */
@@ -1128,6 +1182,8 @@ static void print_queue_update_with_lock(int snum)
struct printif *current_printif = get_printer_fns( snum );
fstrcpy(sharename, lp_const_servicename(snum));
+
+ DEBUG(5,("print_queue_update_with_lock: printer share = %s\n", sharename));
pdb = get_print_db_byname(sharename);
if (!pdb)
return;
@@ -1147,7 +1203,7 @@ static void print_queue_update_with_lock(int snum)
slprintf(keystr, sizeof(keystr) - 1, "LOCK/%s", sharename);
/* 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", sharename));
+ DEBUG(0,("print_queue_update_with_lock: Failed to lock printer %s database\n", sharename));
release_print_db(pdb);
return;
}
@@ -1172,7 +1228,7 @@ static void print_queue_update_with_lock(int snum)
*/
/* Tell others we're doing the update. */
- set_updating_pid(sharename, False);
+ set_updating_pid(sharename, True);
/*
* Allow others to enter and notice we're doing
@@ -1192,7 +1248,7 @@ static void print_queue_update_with_lock(int snum)
print_queue_update_internal( sharename, current_printif, lpq_command );
/* Delete our pid from the db. */
- set_updating_pid(sharename, True);
+ set_updating_pid(sharename, False);
release_print_db(pdb);
}
@@ -1290,6 +1346,11 @@ static void print_queue_update(int snum)
pstrcpy(ctx.lpqcommand, lp_lpqcommand(snum));
pstring_sub( ctx.lpqcommand, "%p", PRINTERNAME(snum) );
standard_sub_snum( snum, ctx.lpqcommand, sizeof(ctx.lpqcommand) );
+
+ DEBUG(10,("print_queue_update: Sending message -> printer = %s, "
+ "type = %d, lpq command = [%s]\n",
+ ctx.sharename, ctx.printing_type, ctx.lpqcommand ));
+
become_root();
message_send_pid(background_lpq_updater_pid,
@@ -1897,45 +1958,6 @@ int print_job_write(int snum, uint32 jobid, const char *buf, int size)
}
/****************************************************************************
- Check if the print queue has been updated recently enough.
-****************************************************************************/
-
-static BOOL print_cache_expired(int snum)
-{
- fstring key;
- time_t last_qscan_time, time_now = time(NULL);
- const char *printername = lp_const_servicename(snum);
- struct tdb_print_db *pdb = get_print_db_byname(printername);
-
- if (!pdb)
- return False;
-
- slprintf(key, sizeof(key), "CACHE/%s", printername);
- last_qscan_time = (time_t)tdb_fetch_int32(pdb->tdb, key);
-
- /*
- * Invalidate the queue for 3 reasons.
- * (1). last queue scan time == -1.
- * (2). Current time - last queue scan time > allowed cache time.
- * (3). last queue scan time > current time + MAX_CACHE_VALID_TIME (1 hour by default).
- * This last test picks up machines for which the clock has been moved
- * forward, an lpq scan done and then the clock moved back. Otherwise
- * that last lpq scan would stay around for a loooong loooong time... :-). JRA.
- */
-
- if (last_qscan_time == ((time_t)-1) || (time_now - last_qscan_time) >= lp_lpqcachetime() ||
- last_qscan_time > (time_now + MAX_CACHE_VALID_TIME)) {
- DEBUG(3, ("print cache expired for queue %s \
-(last_qscan_time = %d, time now = %d, qcachetime = %d)\n", printername,
- (int)last_qscan_time, (int)time_now, (int)lp_lpqcachetime() ));
- release_print_db(pdb);
- return True;
- }
- release_print_db(pdb);
- return False;
-}
-
-/****************************************************************************
Get the queue status - do not update if db is out of date.
****************************************************************************/
@@ -1979,7 +2001,7 @@ int print_queue_length(int snum, print_status_struct *pstatus)
int len;
/* make sure the database is up to date */
- if (print_cache_expired(snum))
+ if (print_cache_expired(lp_const_servicename(snum)))
print_queue_update(snum);
/* also fetch the queue status */
@@ -2294,7 +2316,7 @@ BOOL print_job_end(int snum, uint32 jobid, BOOL normal_close)
pjob_store(sharename, jobid, pjob);
/* make sure the database is up to date */
- if (print_cache_expired(snum))
+ if (print_cache_expired(lp_const_servicename(snum)))
print_queue_update(snum);
return True;
@@ -2326,7 +2348,7 @@ static BOOL get_stored_queue_info(struct tdb_print_db *pdb, int snum, int *pcoun
const char* sharename = lp_servicename(snum);
/* make sure the database is up to date */
- if (print_cache_expired(snum))
+ if (print_cache_expired(lp_const_servicename(snum)))
print_queue_update(snum);
*pcount = 0;
@@ -2447,7 +2469,7 @@ int print_queue_status(int snum,
/* make sure the database is up to date */
- if (print_cache_expired(snum))
+ if (print_cache_expired(lp_const_servicename(snum)))
print_queue_update(snum);
/* return if we are done */
@@ -2547,7 +2569,7 @@ BOOL print_queue_resume(struct current_user *user, int snum, WERROR *errcode)
}
/* make sure the database is up to date */
- if (print_cache_expired(snum))
+ if (print_cache_expired(lp_const_servicename(snum)))
print_queue_update(snum);
/* Send a printer notify message */