smbd: only reprocess printer_list.tdb if it changed
authorDavid Disseldorp <ddiss@samba.org>
Wed, 23 Jul 2014 12:42:00 +0000 (14:42 +0200)
committerAndreas Schneider <asn@cryptomilk.org>
Fri, 8 Aug 2014 12:10:39 +0000 (14:10 +0200)
The per-client smbd printer share inventory is currently updated from
printer_list.tdb when a client enumerates printers, via EnumPrinters or
NetShareEnum.
printer_list.tdb is populated by the background print process, based on
the latest printcap values retrieved from the printing backend (e.g.
CUPS) at regular intervals.
This change ensures that per-client smbd processes don't reparse
printer_list.tdb if it hasn't been updated since the last enumeration.

Bug: https://bugzilla.samba.org/show_bug.cgi?id=10652

Suggested-by: Volker Lendecke <vl@samba.org>
Signed-off-by: David Disseldorp <ddiss@samba.org>
Reviewed-by: Andreas Schneider <asn@samba.org>
source3/smbd/server_reload.c

index 627ad8ba224dd90f8f3869c26d1e782deaf3d801..1477f00c964c45fbe69347be2df9471aa2d5aed1 100644 (file)
 #include "messages.h"
 #include "lib/param/loadparm.h"
 
+/*
+ * The persistent pcap cache is populated by the background print process. Per
+ * client smbds should only reload their printer share inventories if this
+ * information has changed. Use reload_last_pcap_time to detect this.
+ */
+static time_t reload_last_pcap_time = 0;
+
 static bool snum_is_shared_printer(int snum)
 {
        return (lp_browseable(snum) && lp_snum_ok(snum) && lp_printable(snum));
@@ -61,6 +68,20 @@ void delete_and_reload_printers(struct tevent_context *ev,
        const char *pname;
        const char *sname;
        NTSTATUS status;
+       bool ok;
+       time_t pcap_last_update;
+
+       ok = pcap_cache_loaded(&pcap_last_update);
+       if (!ok) {
+               DEBUG(1, ("pcap cache not loaded\n"));
+               return;
+       }
+
+       if (reload_last_pcap_time == pcap_last_update) {
+               DEBUG(5, ("skipping printer reload, already up to date.\n"));
+               return;
+       }
+       reload_last_pcap_time = pcap_last_update;
 
        /* Get pcap printers updated */
        load_printers(ev, msg_ctx);