From: Alex Rousskov Date: Thu, 27 Jan 2011 21:16:49 +0000 (-0700) Subject: Miscellaneous useful changes from 3p1-rock (r9630) unrelated to Rock Store. X-Git-Tag: take01~28 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=f5f9e44c983193ed18d7af76dea168173a0cc35e;p=thirdparty%2Fsquid.git Miscellaneous useful changes from 3p1-rock (r9630) unrelated to Rock Store. --- diff --git a/src/Server.cc b/src/Server.cc index 8256a1f77a..59d27d14af 100644 --- a/src/Server.cc +++ b/src/Server.cc @@ -379,10 +379,10 @@ ServerStateData::sentRequestBody(const CommIoCbParams &io) } if (io.flag) { - debugs(11, 1, "sentRequestBody error: FD " << io.fd << ": " << xstrerr(errno)); + debugs(11, 1, "sentRequestBody error: FD " << io.fd << ": " << xstrerr(io.xerrno)); ErrorState *err; err = errorCon(ERR_WRITE_ERROR, HTTP_BAD_GATEWAY, fwd->request); - err->xerrno = errno; + err->xerrno = io.xerrno; fwd->fail(err); abortTransaction("I/O error while sending request body"); return; diff --git a/src/adaptation/ServiceConfig.cc b/src/adaptation/ServiceConfig.cc index 176ce2110a..612432365f 100644 --- a/src/adaptation/ServiceConfig.cc +++ b/src/adaptation/ServiceConfig.cc @@ -69,6 +69,7 @@ Adaptation::ServiceConfig::parse() // handle optional service name=value parameters const char *lastOption = NULL; + bool grokkedUri = false; while (char *option = strtok(NULL, w_space)) { if (strcmp(option, "0") == 0) { // backward compatibility bypass = false; @@ -94,6 +95,8 @@ Adaptation::ServiceConfig::parse() grokked = grokBool(bypass, name, value); else if (strcmp(name, "routing") == 0) grokked = grokBool(routing, name, value); + else if (strcmp(name, "uri") == 0) + grokked = grokkedUri = grokUri(value); else if (strcmp(name, "ipv6") == 0) { grokked = grokBool(ipv6, name, value); if (grokked && ipv6 && !Ip::EnableIpv6) @@ -107,7 +110,7 @@ Adaptation::ServiceConfig::parse() } // what is left must be the service URI - if (!grokUri(lastOption)) + if (!grokkedUri && !grokUri(lastOption)) return false; // there should be nothing else left diff --git a/src/adaptation/icap/Elements.cc b/src/adaptation/icap/Elements.cc index 17a26130d7..ac82c70ad4 100644 --- a/src/adaptation/icap/Elements.cc +++ b/src/adaptation/icap/Elements.cc @@ -8,6 +8,7 @@ namespace Icap { const XactOutcome xoUnknown = "ICAP_ERR_UNKNOWN"; +const XactOutcome xoGone = "ICAP_ERR_GONE"; const XactOutcome xoRace = "ICAP_ERR_RACE"; const XactOutcome xoError = "ICAP_ERR_OTHER"; const XactOutcome xoOpt = "ICAP_OPT"; diff --git a/src/adaptation/icap/Elements.h b/src/adaptation/icap/Elements.h index ec78a55f6c..1e9ad8e18c 100644 --- a/src/adaptation/icap/Elements.h +++ b/src/adaptation/icap/Elements.h @@ -64,6 +64,7 @@ using Adaptation::vectPointStr; typedef const char *XactOutcome; ///< transaction result for logging extern const XactOutcome xoUnknown; ///< initial value: outcome was not set +extern const XactOutcome xoGone; ///< initiator gone, will not continue extern const XactOutcome xoRace; ///< ICAP server closed pconn when we started extern const XactOutcome xoError; ///< all kinds of transaction errors extern const XactOutcome xoOpt; ///< OPTION transaction diff --git a/src/adaptation/icap/ServiceRep.h b/src/adaptation/icap/ServiceRep.h index fa67bde23a..54fb70c3cd 100644 --- a/src/adaptation/icap/ServiceRep.h +++ b/src/adaptation/icap/ServiceRep.h @@ -92,6 +92,8 @@ public: virtual void finalize(); + void invalidate(); // call when the service is no longer needed or valid + virtual bool probed() const; // see comments above virtual bool up() const; // see comments above diff --git a/src/adaptation/icap/Xaction.cc b/src/adaptation/icap/Xaction.cc index 3e1f3b5d41..b327fe0065 100644 --- a/src/adaptation/icap/Xaction.cc +++ b/src/adaptation/icap/Xaction.cc @@ -196,10 +196,14 @@ void Adaptation::Icap::Xaction::closeConnection() theService->cfg().port, NULL, client_addr); disableRetries(); } else { - //status() adds leading spaces. - debugs(93,3, HERE << "closing pconn" << status()); + const bool reset = al.icap.outcome == xoGone || al.icap.outcome == xoError; + debugs(93,3, HERE << (reset ? "RST" : "FIN") << "-closing" << + status()); // comm_close will clear timeout - comm_close(connection); + if (reset) + comm_reset_close(connection); + else + comm_close(connection); } writer = NULL; @@ -444,8 +448,10 @@ void Adaptation::Icap::Xaction::noteInitiatorAborted() { if (theInitiator.set()) { + debugs(93,4, HERE << "Initiator gone before ICAP transaction ended"); clearInitiator(); detailError(ERR_DETAIL_ICAP_INIT_GONE); + setOutcome(xoGone); mustStop("initiator aborted"); } diff --git a/src/client_side.cc b/src/client_side.cc index d961801a5f..8943d7b8b8 100644 --- a/src/client_side.cc +++ b/src/client_side.cc @@ -615,7 +615,10 @@ prepareLogWithRequestDetails(HttpRequest * request, AccessLogEntry * aLogEntry) void ClientHttpRequest::logRequest() { - if (out.size || logType) { + if (!out.size && !logType) + debugs(33,2, HERE << "logging half-baked transaction: " << log_uri); + + if (true) { al.icp.opcode = ICP_INVALID; al.url = log_uri; debugs(33, 9, "clientLogRequest: al.url='" << al.url << "'"); @@ -2244,8 +2247,10 @@ parseHttpRequest(ConnStateData *conn, HttpParser *hp, HttpRequestMethod * method int ConnStateData::getAvailableBufferLength() const { - int result = in.allocatedSize - in.notYetUsed - 1; - assert (result >= 0); + assert (in.allocatedSize > in.notYetUsed); // allocated more than used + const size_t result = in.allocatedSize - in.notYetUsed - 1; + // huge request_header_max_size may lead to more than INT_MAX unused space + assert (static_cast(result) <= INT_MAX); return result; } diff --git a/src/ipcache.cc b/src/ipcache.cc index 926b906e5c..b4a1f725a6 100644 --- a/src/ipcache.cc +++ b/src/ipcache.cc @@ -161,6 +161,9 @@ static long ipcache_high = 200; extern int _dns_ttl_; #endif +/// \ingroup IPCacheInternal +inline int ipcacheCount() { return ip_table ? ip_table->count : 0; } + int ipcache_entry::age() const { @@ -235,7 +238,7 @@ ipcache_purgelru(void *voidnotused) eventAdd("ipcache_purgelru", ipcache_purgelru, NULL, 10.0, 1); for (m = lru_list.tail; m; m = prev) { - if (memInUse(MEM_IPCACHE_ENTRY) < ipcache_low) + if (ipcacheCount() < ipcache_low) break; prev = m->prev; @@ -855,8 +858,10 @@ stat_ipcache_get(StoreEntry * sentry) dlink_node *m; assert(ip_table != NULL); storeAppendPrintf(sentry, "IP Cache Statistics:\n"); - storeAppendPrintf(sentry, "IPcache Entries: %d\n", + storeAppendPrintf(sentry, "IPcache Entries In Use: %d\n", memInUse(MEM_IPCACHE_ENTRY)); + storeAppendPrintf(sentry, "IPcache Entries Cached: %d\n", + ipcacheCount()); storeAppendPrintf(sentry, "IPcache Requests: %d\n", IpcacheStats.requests); storeAppendPrintf(sentry, "IPcache Hits: %d\n", @@ -1231,7 +1236,7 @@ snmp_netIpFn(variable_list * Var, snint * ErrP) case IP_ENT: Answer = snmp_var_new_integer(Var->name, Var->name_length, - memInUse(MEM_IPCACHE_ENTRY), + ipcacheCount(), SMI_GAUGE32); break; diff --git a/src/log/FormatSquidCustom.cc b/src/log/FormatSquidCustom.cc index f1a031ceac..67d45a23b9 100644 --- a/src/log/FormatSquidCustom.cc +++ b/src/log/FormatSquidCustom.cc @@ -794,11 +794,18 @@ Log::Format::SquidCustom(AccessLogEntry * al, customlog * log) } } - if (fmt->width) { + // enforce width limits if configured + const bool haveMaxWidth = fmt->precision && !doint && !dooff; + if (haveMaxWidth || fmt->width) { + const int minWidth = fmt->width ? + static_cast(fmt->width) : 0; + const int maxWidth = haveMaxWidth ? + static_cast(fmt->precision) : strlen(out); + if (fmt->left) - mb.Printf("%-*s", (int) fmt->width, out); + mb.Printf("%-*.*s", minWidth, maxWidth, out); else - mb.Printf("%*s", (int) fmt->width, out); + mb.Printf("%*.*s", minWidth, maxWidth, out); } else mb.append(out, strlen(out)); } else { diff --git a/src/log/FormatSquidIcap.cc b/src/log/FormatSquidIcap.cc index 5fccc88f9e..929d881713 100644 --- a/src/log/FormatSquidIcap.cc +++ b/src/log/FormatSquidIcap.cc @@ -75,11 +75,12 @@ Log::Format::SquidIcap(AccessLogEntry * al, Logfile * logfile) if (user && !*user) safe_free(user); - logfilePrintf(logfile, "%9ld.%03d %6d %s -/%03d %"PRId64" %s %s %s -/%s -\n", + logfilePrintf(logfile, "%9ld.%03d %6d %s %s/%03d %"PRId64" %s %s %s -/%s -\n", (long int) current_time.tv_sec, (int) current_time.tv_usec / 1000, al->icap.trTime, client, + al->icap.outcome, al->icap.resStatus, al->icap.bytesRead, Adaptation::Icap::ICAP::methodStr(al->icap.reqMethod), diff --git a/src/log/Tokens.h b/src/log/Tokens.h index 36316d454e..0890c04d65 100644 --- a/src/log/Tokens.h +++ b/src/log/Tokens.h @@ -189,8 +189,8 @@ public: } header; char *timespec; } data; - unsigned char width; - unsigned char precision; + unsigned int width; + unsigned int precision; enum log_quote quote; unsigned int left:1; unsigned int space:1; diff --git a/src/main.cc b/src/main.cc index 662c6ef629..597f03d579 100644 --- a/src/main.cc +++ b/src/main.cc @@ -1208,10 +1208,10 @@ SquidMainSafe(int argc, char **argv) try { return SquidMain(argc, argv); } catch (const std::exception &e) { - std::cerr << "dying from an unhandled exception: " << e.what() << std::endl; + debugs(0,0, "dying from an unhandled exception: " << e.what()); throw; } catch (...) { - std::cerr << "dying from an unhandled exception." << std::endl; + debugs(0,0, "dying from an unhandled exception."); throw; } return -1; // not reached diff --git a/src/mem.cc b/src/mem.cc index 9970cd39b5..14b5c94a9a 100644 --- a/src/mem.cc +++ b/src/mem.cc @@ -489,7 +489,8 @@ void memClean(void) { MemPoolGlobalStats stats; - MemPools::GetInstance().setIdleLimit(0); + if (Config.MemPools.limit > 0) // do not reset if disabled or same + MemPools::GetInstance().setIdleLimit(0); MemPools::GetInstance().clean(0); memPoolGetGlobalStats(&stats); diff --git a/src/store.cc b/src/store.cc index 72f7d0829d..f9b692402f 100644 --- a/src/store.cc +++ b/src/store.cc @@ -254,6 +254,16 @@ StoreEntry::delayAwareRead(int fd, char *buf, int len, AsyncCall::Pointer callba } + if (fd_table[fd].closing()) { + // Readers must have closing callbacks if they want to be notified. No + // readers appeared to care around 2009/12/14 as they skipped reading + // for other reasons. Closing may already be true at the delyaAwareRead + // call time or may happen while we wait after delayRead() above. + debugs(20, 3, HERE << "wont read from closing FD " << fd << " for " << + callback); + return; // the read callback will never be called + } + comm_read(fd, buf, amountToRead, callback); }