diff options
author | Volker Lendecke <vl@samba.org> | 2010-08-27 14:44:16 +0200 |
---|---|---|
committer | Volker Lendecke <vl@samba.org> | 2010-08-27 16:47:07 +0200 |
commit | e8cfc2f1de4b60f192a391dd02e405a152a7d5a6 (patch) | |
tree | 7c3e382043fb33f144a89bd0fb0df95eb1cc5919 | |
parent | 44b2a7941c1da4c565cb14bae7acc355787ecc6e (diff) | |
download | samba-e8cfc2f1de4b60f192a391dd02e405a152a7d5a6.tar.gz samba-e8cfc2f1de4b60f192a391dd02e405a152a7d5a6.tar.bz2 samba-e8cfc2f1de4b60f192a391dd02e405a152a7d5a6.zip |
s3: Cache results of finding printer names
With hundreds of printers or on a slow machine, this can become expensive.
Problem reported and patch sponsored by DESY, Hamburg (www.desy.de)
-rw-r--r-- | source3/rpc_server/srv_spoolss_nt.c | 39 |
1 files changed, 39 insertions, 0 deletions
diff --git a/source3/rpc_server/srv_spoolss_nt.c b/source3/rpc_server/srv_spoolss_nt.c index 5df20d4f08..4e97122736 100644 --- a/source3/rpc_server/srv_spoolss_nt.c +++ b/source3/rpc_server/srv_spoolss_nt.c @@ -470,6 +470,14 @@ static bool set_printer_hnd_name(TALLOC_CTX *mem_ctx, struct spoolss_PrinterInfo2 *info2 = NULL; WERROR result; + /* + * Hopefully nobody names his printers like this. Maybe \ or , + * are illegal in printer names even? + */ + const char printer_not_found[] = "Printer \\, !@#$%^&*( not found"; + char *cache_key; + char *tmp; + DEBUG(4,("Setting printer name=%s (len=%lu)\n", handlename, (unsigned long)strlen(handlename))); @@ -509,6 +517,27 @@ static bool set_printer_hnd_name(TALLOC_CTX *mem_ctx, found = true; } + /* + * With hundreds of printers, the "for" loop iterating all + * shares can be quite expensive, as it is done on every + * OpenPrinter. The loop maps "aprinter" to "sname", the + * result of which we cache in gencache. + */ + + cache_key = talloc_asprintf(talloc_tos(), "PRINTERNAME/%s", + aprinter); + if ((cache_key != NULL) && gencache_get(cache_key, &tmp, NULL)) { + + found = (strcmp(tmp, printer_not_found) != 0); + if (!found) { + DEBUG(4, ("Printer %s not found\n", aprinter)); + SAFE_FREE(tmp); + return false; + } + fstrcpy(sname, tmp); + SAFE_FREE(tmp); + } + /* Search all sharenames first as this is easier than pulling the printer_info_2 off of disk. Don't use find_service() since that calls out to map_username() */ @@ -569,10 +598,20 @@ static bool set_printer_hnd_name(TALLOC_CTX *mem_ctx, } if ( !found ) { + if (cache_key != NULL) { + gencache_set(cache_key, printer_not_found, + time(NULL)+300); + TALLOC_FREE(cache_key); + } DEBUGADD(4,("Printer not found\n")); return false; } + if (cache_key != NULL) { + gencache_set(cache_key, sname, time(NULL)+300); + TALLOC_FREE(cache_key); + } + DEBUGADD(4,("set_printer_hnd_name: Printer found: %s -> %s\n", aprinter, sname)); fstrcpy(Printer->sharename, sname); |